<commit_before>{-
Copyright 2016 SlamData, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-}

module SlamData.Notebook.Deck.Component
  ( comp
  , initialState
  , module SlamData.Notebook.Deck.Component.Query
  , module DCS
  ) where

import SlamData.Prelude

import Control.Monad.Aff.Console (log)
import Control.Monad.Eff.Exception as Exn
import Control.Monad.Except.Trans (ExceptT(..), runExceptT)
import Control.UI.Browser (newTab, locationObject)
import Control.Monad.Aff.Free (fromEff)

import CSS.Geometry (width)
import CSS.Size (pct, Size(..), Rel, nil)
import CSS.String (fromString)
import CSS.Transform (transform, translate)

import Data.Argonaut (Json)
import Data.Array (catMaybes, nub)
import Data.BrowserFeatures (BrowserFeatures)
import Data.Int (toNumber)
import Data.Lens as Lens
import Data.Lens (LensP(), view, (.~), (%~), (?~), (^?))
import Data.Lens.Prism.Coproduct (_Right)
import Data.List as List
import Data.Map as Map
import Data.Ord (max)
import Data.Path.Pathy ((</>))
import Data.Path.Pathy as Pathy
import Data.Set as S
import Data.String as Str
import Data.Time (Milliseconds(..))

import Ace.Halogen.Component as Ace

import DOM.HTML.Location as Location

import Halogen as H
import Halogen.Component.ChildPath (ChildPath, injSlot, injState)
import Halogen.Component.Utils (forceRerender')
import Halogen.Component.Utils.Debounced (fireDebouncedQuery')
import Halogen.HTML.CSS.Indexed (style)
import Halogen.HTML.Events.Indexed as HE
import Halogen.HTML.Events.Handler as HEH
import Halogen.HTML.Indexed as HH
import Halogen.Component.ChildPath (injSlot, injState)
import Halogen.HTML.Properties.Indexed as HP
import Halogen.Themes.Bootstrap3 as B
import Halogen.HTML.Properties.Indexed.ARIA as ARIA
import Quasar.Aff as Quasar
import Quasar.Auth as Auth

import SlamData.Config as Config
import SlamData.Effects (Slam)
import SlamData.FileSystem.Resource as R
import SlamData.Notebook.AccessType (AccessType(..), isEditable)
import SlamData.Notebook.Action as NA
import SlamData.Notebook.Card.CardId (CardId(), runCardId, cardIdToString)
import SlamData.Notebook.Card.CardType
  (CardType(..), AceMode(..), cardName, cardGlyph, autorun, nextCardTypes)
import SlamData.Notebook.Card.Common.EvalQuery (CardEvalQuery(..))
import SlamData.Notebook.Card.Component (CardQueryP, CardQuery(..), InnerCardQuery, AnyCardQuery(..), _NextQuery, initialCardState)
import SlamData.Notebook.Card.Next.Component as Next
import SlamData.Notebook.Card.OpenResource.Component as Open
import SlamData.Notebook.Card.Port (Port(..))
import SlamData.Notebook.Deck.BackSide.Component as Back
import SlamData.Notebook.Deck.Component.ChildSlot (cpBackSide, cpCard, ChildQuery, ChildState, ChildSlot, CardSlot(..))
import SlamData.Notebook.Deck.Component.Query (QueryP, Query(..))

import SlamData.Notebook.Deck.Component.State as DCS
import SlamData.Notebook.Deck.DeckId (DeckId(..), deckIdToString)
import SlamData.Notebook.Deck.Model as Model
import SlamData.Notebook.Model as NB
import SlamData.Notebook.Routing (mkNotebookHash, mkNotebookCardHash, mkNotebookURL)
import SlamData.Quasar.Data (save, load) as Quasar
import SlamData.Quasar.FS (move, getNewName) as Quasar
import SlamData.Render.CSS as CSS
import Utils.Debounced (debouncedEventSource)
import Utils.Path (DirPath, FilePath)
import Utils.DOM (getBoundingClientRect, offsetLeft)
import Utils.CSS (transition)

type NotebookHTML = H.ParentHTML ChildState Query ChildQuery Slam ChildSlot
type NotebookDSL = H.ParentDSL DCS.State ChildState Query ChildQuery Slam ChildSlot

initialState ∷ BrowserFeatures → DCS.StateP
initialState fs = H.parentState $ DCS.initialDeck fs

comp ∷ H.Component DCS.StateP QueryP Slam
comp =
  H.parentComponent
    { render: render ∘ DCS.virtualState
    , eval
    , peek: Just peek
    }

render ∷ DCS.State → NotebookHTML
render state =
  case state.stateMode of
    DCS.Loading →
      HH.div
        [ HP.classes [ B.alert, B.alertInfo ] ]
        [ HH.h1
          [ HP.class_ B.textCenter ]
          [ HH.text "Loading..." ]
          -- We need to render the cards but have them invisible during loading
          -- otherwise the various nested components won't initialise correctly
        , renderCards false
        ]
    DCS.Ready →
      -- WARNING: Very strange things happen when this is not in a div; see SD-1326.
      HH.div
        ([ HP.class_ CSS.board ]
           ⊕ (guard (isJust state.initialSliderX)
                $> (HE.onMouseUp \e -> HEH.preventDefault $> H.action (StopSlidingAndSnap e)))
           ⊕ (guard (isJust state.initialSliderX)
                $> (HE.onMouseLeave \e -> HEH.stopPropagation $> HEH.preventDefault $> H.action (StopSlidingAndSnap e)))
           ⊕ (guard (isJust state.initialSliderX)
                $> (HE.onMouseMove $ HE.input UpdateSliderPosition)))
        [ HH.div
            [ HP.class_ CSS.deck ]
            [ renderCards $ not state.backsided
            , renderBackside state.backsided<commit_msg>Fix one-card component init with `key` & structure fix<commit_after>{-
Copyright 2016 SlamData, Inc.

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-}

module SlamData.Notebook.Deck.Component
  ( comp
  , initialState
  , module SlamData.Notebook.Deck.Component.Query
  , module DCS
  ) where

import SlamData.Prelude

import Control.Monad.Aff.Console (log)
import Control.Monad.Eff.Exception as Exn
import Control.Monad.Except.Trans (ExceptT(..), runExceptT)
import Control.UI.Browser (newTab, locationObject)
import Control.Monad.Aff.Free (fromEff)

import CSS.Geometry (width)
import CSS.Size (pct, Size(..), Rel, nil)
import CSS.String (fromString)
import CSS.Transform (transform, translate)

import Data.Argonaut (Json)
import Data.Array (catMaybes, nub)
import Data.BrowserFeatures (BrowserFeatures)
import Data.Int (toNumber)
import Data.Lens as Lens
import Data.Lens (LensP(), view, (.~), (%~), (?~), (^?))
import Data.Lens.Prism.Coproduct (_Right)
import Data.List as List
import Data.Map as Map
import Data.Ord (max)
import Data.Path.Pathy ((</>))
import Data.Path.Pathy as Pathy
import Data.Set as S
import Data.String as Str
import Data.Time (Milliseconds(..))

import Ace.Halogen.Component as Ace

import DOM.HTML.Location as Location

import Halogen as H
import Halogen.Component.ChildPath (ChildPath, injSlot, injState)
import Halogen.Component.Utils (forceRerender')
import Halogen.Component.Utils.Debounced (fireDebouncedQuery')
import Halogen.HTML.CSS.Indexed (style)
import Halogen.HTML.Events.Indexed as HE
import Halogen.HTML.Events.Handler as HEH
import Halogen.HTML.Indexed as HH
import Halogen.Component.ChildPath (injSlot, injState)
import Halogen.HTML.Properties.Indexed as HP
import Halogen.Themes.Bootstrap3 as B
import Halogen.HTML.Properties.Indexed.ARIA as ARIA
import Quasar.Aff as Quasar
import Quasar.Auth as Auth

import SlamData.Config as Config
import SlamData.Effects (Slam)
import SlamData.FileSystem.Resource as R
import SlamData.Notebook.AccessType (AccessType(..), isEditable)
import SlamData.Notebook.Action as NA
import SlamData.Notebook.Card.CardId (CardId(), runCardId, cardIdToString)
import SlamData.Notebook.Card.CardType
  (CardType(..), AceMode(..), cardName, cardGlyph, autorun, nextCardTypes)
import SlamData.Notebook.Card.Common.EvalQuery (CardEvalQuery(..))
import SlamData.Notebook.Card.Component (CardQueryP, CardQuery(..), InnerCardQuery, AnyCardQuery(..), _NextQuery, initialCardState)
import SlamData.Notebook.Card.Next.Component as Next
import SlamData.Notebook.Card.OpenResource.Component as Open
import SlamData.Notebook.Card.Port (Port(..))
import SlamData.Notebook.Deck.BackSide.Component as Back
import SlamData.Notebook.Deck.Component.ChildSlot (cpBackSide, cpCard, ChildQuery, ChildState, ChildSlot, CardSlot(..))
import SlamData.Notebook.Deck.Component.Query (QueryP, Query(..))

import SlamData.Notebook.Deck.Component.State as DCS
import SlamData.Notebook.Deck.DeckId (DeckId(..), deckIdToString)
import SlamData.Notebook.Deck.Model as Model
import SlamData.Notebook.Model as NB
import SlamData.Notebook.Routing (mkNotebookHash, mkNotebookCardHash, mkNotebookURL)
import SlamData.Quasar.Data (save, load) as Quasar
import SlamData.Quasar.FS (move, getNewName) as Quasar
import SlamData.Render.CSS as CSS
import Utils.Debounced (debouncedEventSource)
import Utils.Path (DirPath, FilePath)
import Utils.DOM (getBoundingClientRect, offsetLeft)
import Utils.CSS (transition)

type NotebookHTML = H.ParentHTML ChildState Query ChildQuery Slam ChildSlot
type NotebookDSL = H.ParentDSL DCS.State ChildState Query ChildQuery Slam ChildSlot

initialState ∷ BrowserFeatures → DCS.StateP
initialState fs = H.parentState $ DCS.initialDeck fs

comp ∷ H.Component DCS.StateP QueryP Slam
comp =
  H.parentComponent
    { render: render ∘ DCS.virtualState
    , eval
    , peek: Just peek
    }

render ∷ DCS.State → NotebookHTML
render state =
  case state.stateMode of
    DCS.Loading →
      HH.div
        [ HP.classes [ B.alert, B.alertInfo ] ]
        [ HH.h1
          [ HP.class_ B.textCenter ]
          [ HH.text "Loading..." ]
          -- We need to render the cards but have them invisible during loading
          -- otherwise the various nested components won't initialise correctly.
          -- This div is required, along with the key, so that structurally it
          -- is in the same place in both `Loading` and `Ready` states.
        , HH.div
            [ HP.key "deck-container" ]
            [ renderCards false ]
        ]
    DCS.Ready →
      -- WARNING: Very strange things happen when this is not in a div; see SD-1326.
      HH.div
        ([ HP.class_ CSS.board ]
           ⊕ (guard (isJust state.initialSliderX)
                $> (HE.onMouseUp \e -> HEH.preventDefault $> H.action (StopSlidingAndSnap e)))
           ⊕ (guard (isJust state.initialSliderX)
                $> (HE.onMouseLeave \e -> HEH.stopPropagation $> HEH.preventDefault $> H.action (StopSlidingAndSnap e)))
           ⊕ (guard (isJust state.initialSliderX)
                $> (HE.onMouseMove $ HE.input UpdateSliderPosition)))
        [ HH.div
            [ HP.class_ CSS.deck
            , HP.key "deck-container"
            ]
            [ renderCards $ not state.backsided
            , renderBackside state.backsided
{'fraction_non_alphanumeric': 0.09680870030308433, 'fraction_numerical': 0.002495988589766447, 'mean_word_length': 3.88207136640557, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 21, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3941902', 'n_tokens_mistral': 3567, 'n_tokens_neox': 3475, 'n_words': 1042}