module Matterhorn.State.UrlSelect
  (
  -- * URL selection mode
    startUrlSelect
  , stopUrlSelect
  , openSelectedURL
  )
where

import           Prelude ()
import           Matterhorn.Prelude

import           Brick.Widgets.List ( list, listMoveTo, listSelectedElement )
import qualified Data.Vector as V
import           Lens.Micro.Platform ( (.=), to )

import           Matterhorn.State.Links
import           Matterhorn.Types
import           Matterhorn.Util


startUrlSelect :: MH ()
startUrlSelect :: MH ()
startUrlSelect = do
    Vector LinkChoice
urls <- Getting (Vector LinkChoice) ChatState (Vector LinkChoice)
-> MH (Vector LinkChoice)
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((ClientChannel -> Const (Vector LinkChoice) ClientChannel)
-> ChatState -> Const (Vector LinkChoice) ChatState
Lens' ChatState ClientChannel
csCurrentChannel((ClientChannel -> Const (Vector LinkChoice) ClientChannel)
 -> ChatState -> Const (Vector LinkChoice) ChatState)
-> ((Vector LinkChoice
     -> Const (Vector LinkChoice) (Vector LinkChoice))
    -> ClientChannel -> Const (Vector LinkChoice) ClientChannel)
-> Getting (Vector LinkChoice) ChatState (Vector LinkChoice)
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(ClientChannel -> [LinkChoice])
-> SimpleGetter ClientChannel [LinkChoice]
forall s a. (s -> a) -> SimpleGetter s a
to ClientChannel -> [LinkChoice]
findUrlsGetting (Vector LinkChoice) ClientChannel [LinkChoice]
-> ((Vector LinkChoice
     -> Const (Vector LinkChoice) (Vector LinkChoice))
    -> [LinkChoice] -> Const (Vector LinkChoice) [LinkChoice])
-> (Vector LinkChoice
    -> Const (Vector LinkChoice) (Vector LinkChoice))
-> ClientChannel
-> Const (Vector LinkChoice) ClientChannel
forall b c a. (b -> c) -> (a -> b) -> a -> c
.([LinkChoice] -> Vector LinkChoice)
-> SimpleGetter [LinkChoice] (Vector LinkChoice)
forall s a. (s -> a) -> SimpleGetter s a
to [LinkChoice] -> Vector LinkChoice
forall a. [a] -> Vector a
V.fromList)
    let urlsWithIndexes :: Vector (Int, LinkChoice)
urlsWithIndexes = Vector LinkChoice -> Vector (Int, LinkChoice)
forall a. Vector a -> Vector (Int, a)
V.indexed Vector LinkChoice
urls
    TeamId
tId <- Getting TeamId ChatState TeamId -> MH TeamId
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use Getting TeamId ChatState TeamId
SimpleGetter ChatState TeamId
csCurrentTeamId
    Mode -> MH ()
setMode Mode
UrlSelect
    (TeamState -> Identity TeamState)
-> ChatState -> Identity ChatState
Lens' ChatState TeamState
csCurrentTeam((TeamState -> Identity TeamState)
 -> ChatState -> Identity ChatState)
-> ((List Name (Int, LinkChoice)
     -> Identity (List Name (Int, LinkChoice)))
    -> TeamState -> Identity TeamState)
-> (List Name (Int, LinkChoice)
    -> Identity (List Name (Int, LinkChoice)))
-> ChatState
-> Identity ChatState
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(List Name (Int, LinkChoice)
 -> Identity (List Name (Int, LinkChoice)))
-> TeamState -> Identity TeamState
Lens' TeamState (List Name (Int, LinkChoice))
tsUrlList ((List Name (Int, LinkChoice)
  -> Identity (List Name (Int, LinkChoice)))
 -> ChatState -> Identity ChatState)
-> List Name (Int, LinkChoice) -> MH ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= (Int -> List Name (Int, LinkChoice) -> List Name (Int, LinkChoice)
forall (t :: * -> *) n e.
(Foldable t, Splittable t) =>
Int -> GenericList n t e -> GenericList n t e
listMoveTo (Vector LinkChoice -> Int
forall (t :: * -> *) a. Foldable t => t a -> Int
length Vector LinkChoice
urls Int -> Int -> Int
forall a. Num a => a -> a -> a
- Int
1) (List Name (Int, LinkChoice) -> List Name (Int, LinkChoice))
-> List Name (Int, LinkChoice) -> List Name (Int, LinkChoice)
forall a b. (a -> b) -> a -> b
$ Name
-> Vector (Int, LinkChoice) -> Int -> List Name (Int, LinkChoice)
forall (t :: * -> *) n e.
Foldable t =>
n -> t e -> Int -> GenericList n t e
list (TeamId -> Name
UrlList TeamId
tId) Vector (Int, LinkChoice)
urlsWithIndexes Int
2)

stopUrlSelect :: MH ()
stopUrlSelect :: MH ()
stopUrlSelect = Mode -> MH ()
setMode Mode
Main

openSelectedURL :: MH ()
openSelectedURL :: MH ()
openSelectedURL = Mode -> MH () -> MH ()
whenMode Mode
UrlSelect (MH () -> MH ()) -> MH () -> MH ()
forall a b. (a -> b) -> a -> b
$ do
    Maybe (Int, (Int, LinkChoice))
selected <- Getting
  (Maybe (Int, (Int, LinkChoice)))
  ChatState
  (Maybe (Int, (Int, LinkChoice)))
-> MH (Maybe (Int, (Int, LinkChoice)))
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use ((TeamState -> Const (Maybe (Int, (Int, LinkChoice))) TeamState)
-> ChatState -> Const (Maybe (Int, (Int, LinkChoice))) ChatState
Lens' ChatState TeamState
csCurrentTeam((TeamState -> Const (Maybe (Int, (Int, LinkChoice))) TeamState)
 -> ChatState -> Const (Maybe (Int, (Int, LinkChoice))) ChatState)
-> ((Maybe (Int, (Int, LinkChoice))
     -> Const
          (Maybe (Int, (Int, LinkChoice))) (Maybe (Int, (Int, LinkChoice))))
    -> TeamState -> Const (Maybe (Int, (Int, LinkChoice))) TeamState)
-> Getting
     (Maybe (Int, (Int, LinkChoice)))
     ChatState
     (Maybe (Int, (Int, LinkChoice)))
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(List Name (Int, LinkChoice)
 -> Const
      (Maybe (Int, (Int, LinkChoice))) (List Name (Int, LinkChoice)))
-> TeamState -> Const (Maybe (Int, (Int, LinkChoice))) TeamState
Lens' TeamState (List Name (Int, LinkChoice))
tsUrlList((List Name (Int, LinkChoice)
  -> Const
       (Maybe (Int, (Int, LinkChoice))) (List Name (Int, LinkChoice)))
 -> TeamState -> Const (Maybe (Int, (Int, LinkChoice))) TeamState)
-> ((Maybe (Int, (Int, LinkChoice))
     -> Const
          (Maybe (Int, (Int, LinkChoice))) (Maybe (Int, (Int, LinkChoice))))
    -> List Name (Int, LinkChoice)
    -> Const
         (Maybe (Int, (Int, LinkChoice))) (List Name (Int, LinkChoice)))
-> (Maybe (Int, (Int, LinkChoice))
    -> Const
         (Maybe (Int, (Int, LinkChoice))) (Maybe (Int, (Int, LinkChoice))))
-> TeamState
-> Const (Maybe (Int, (Int, LinkChoice))) TeamState
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(List Name (Int, LinkChoice) -> Maybe (Int, (Int, LinkChoice)))
-> SimpleGetter
     (List Name (Int, LinkChoice)) (Maybe (Int, (Int, LinkChoice)))
forall s a. (s -> a) -> SimpleGetter s a
to List Name (Int, LinkChoice) -> Maybe (Int, (Int, LinkChoice))
forall (t :: * -> *) n e.
(Splittable t, Foldable t) =>
GenericList n t e -> Maybe (Int, e)
listSelectedElement)
    case Maybe (Int, (Int, LinkChoice))
selected of
        Maybe (Int, (Int, LinkChoice))
Nothing -> Mode -> MH ()
setMode Mode
Main
        Just (Int
_, (Int
_, LinkChoice
link)) -> do
            Bool
opened <- LinkTarget -> MH Bool
openLinkTarget (LinkChoice
linkLinkChoice
-> Getting LinkTarget LinkChoice LinkTarget -> LinkTarget
forall s a. s -> Getting a s a -> a
^.Getting LinkTarget LinkChoice LinkTarget
Lens' LinkChoice LinkTarget
linkTarget)
            Bool -> MH () -> MH ()
forall (f :: * -> *). Applicative f => Bool -> f () -> f ()
when (Bool -> Bool
not Bool
opened) (MH () -> MH ()) -> MH () -> MH ()
forall a b. (a -> b) -> a -> b
$ do
                MHError -> MH ()
mhError (MHError -> MH ()) -> MHError -> MH ()
forall a b. (a -> b) -> a -> b
$ Text -> MHError
ConfigOptionMissing Text
"urlOpenCommand"
                Mode -> MH ()
setMode Mode
Main

findUrls :: ClientChannel -> [LinkChoice]
findUrls :: ClientChannel -> [LinkChoice]
findUrls ClientChannel
chan =
    let msgs :: Messages
msgs = ClientChannel
chanClientChannel
-> Getting Messages ClientChannel Messages -> Messages
forall s a. s -> Getting a s a -> a
^.(ChannelContents -> Const Messages ChannelContents)
-> ClientChannel -> Const Messages ClientChannel
Lens' ClientChannel ChannelContents
ccContents((ChannelContents -> Const Messages ChannelContents)
 -> ClientChannel -> Const Messages ClientChannel)
-> ((Messages -> Const Messages Messages)
    -> ChannelContents -> Const Messages ChannelContents)
-> Getting Messages ClientChannel Messages
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Messages -> Const Messages Messages)
-> ChannelContents -> Const Messages ChannelContents
Lens' ChannelContents Messages
cdMessages
    in [LinkChoice] -> [LinkChoice]
removeDuplicates ([LinkChoice] -> [LinkChoice]) -> [LinkChoice] -> [LinkChoice]
forall a b. (a -> b) -> a -> b
$ [[LinkChoice]] -> [LinkChoice]
forall (t :: * -> *) a. Foldable t => t [a] -> [a]
concat ([[LinkChoice]] -> [LinkChoice]) -> [[LinkChoice]] -> [LinkChoice]
forall a b. (a -> b) -> a -> b
$ DirectionalSeq Chronological [LinkChoice] -> [[LinkChoice]]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (DirectionalSeq Chronological [LinkChoice] -> [[LinkChoice]])
-> DirectionalSeq Chronological [LinkChoice] -> [[LinkChoice]]
forall a b. (a -> b) -> a -> b
$ Seq LinkChoice -> [LinkChoice]
forall (t :: * -> *) a. Foldable t => t a -> [a]
toList (Seq LinkChoice -> [LinkChoice])
-> (Message -> Seq LinkChoice) -> Message -> [LinkChoice]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Message -> Seq LinkChoice
msgURLs (Message -> [LinkChoice])
-> Messages -> DirectionalSeq Chronological [LinkChoice]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> Messages
msgs

removeDuplicates :: [LinkChoice] -> [LinkChoice]
removeDuplicates :: [LinkChoice] -> [LinkChoice]
removeDuplicates = (LinkChoice -> (LinkTarget, UserRef, Maybe Inlines))
-> [LinkChoice] -> [LinkChoice]
forall b a. Ord b => (a -> b) -> [a] -> [a]
nubOn (\ LinkChoice
l -> (LinkChoice
lLinkChoice
-> Getting LinkTarget LinkChoice LinkTarget -> LinkTarget
forall s a. s -> Getting a s a -> a
^.Getting LinkTarget LinkChoice LinkTarget
Lens' LinkChoice LinkTarget
linkTarget, LinkChoice
lLinkChoice -> Getting UserRef LinkChoice UserRef -> UserRef
forall s a. s -> Getting a s a -> a
^.Getting UserRef LinkChoice UserRef
Lens' LinkChoice UserRef
linkUser, LinkChoice
lLinkChoice
-> Getting (Maybe Inlines) LinkChoice (Maybe Inlines)
-> Maybe Inlines
forall s a. s -> Getting a s a -> a
^.Getting (Maybe Inlines) LinkChoice (Maybe Inlines)
Lens' LinkChoice (Maybe Inlines)
linkLabel))