{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE RankNTypes #-}
module Matterhorn.State.NotifyPrefs
    ( enterEditNotifyPrefsMode
    , exitEditNotifyPrefsMode
    )
where

import Prelude ()
import Matterhorn.Prelude

import Network.Mattermost.Types ( ChannelNotifyProps
                                , TeamId
                                , User(..)
                                , UserNotifyProps(..)
                                , Type(..)
                                , channelNotifyPropsMarkUnread
                                , channelNotifyPropsIgnoreChannelMentions
                                , WithDefault(..)
                                , NotifyOption(..)
                                )

import Brick
import Brick.Forms
import Lens.Micro.Platform ( Lens', (.=), lens )

import Matterhorn.Types


muteLens :: Lens' ChannelNotifyProps Bool
muteLens :: (Bool -> f Bool) -> ChannelNotifyProps -> f ChannelNotifyProps
muteLens = (ChannelNotifyProps -> Bool)
-> (ChannelNotifyProps -> Bool -> ChannelNotifyProps)
-> Lens ChannelNotifyProps ChannelNotifyProps Bool Bool
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens (\ChannelNotifyProps
props -> ChannelNotifyProps
propsChannelNotifyProps
-> Getting
     (WithDefault NotifyOption)
     ChannelNotifyProps
     (WithDefault NotifyOption)
-> WithDefault NotifyOption
forall s a. s -> Getting a s a -> a
^.Getting
  (WithDefault NotifyOption)
  ChannelNotifyProps
  (WithDefault NotifyOption)
Lens' ChannelNotifyProps (WithDefault NotifyOption)
channelNotifyPropsMarkUnreadL WithDefault NotifyOption -> WithDefault NotifyOption -> Bool
forall a. Eq a => a -> a -> Bool
== NotifyOption -> WithDefault NotifyOption
forall a. a -> WithDefault a
IsValue NotifyOption
NotifyOptionMention)
           (\ChannelNotifyProps
props Bool
muted -> ChannelNotifyProps
props { channelNotifyPropsMarkUnread :: WithDefault NotifyOption
channelNotifyPropsMarkUnread =
                                          if Bool
muted
                                          then NotifyOption -> WithDefault NotifyOption
forall a. a -> WithDefault a
IsValue NotifyOption
NotifyOptionMention
                                          else NotifyOption -> WithDefault NotifyOption
forall a. a -> WithDefault a
IsValue NotifyOption
NotifyOptionAll
                                  })

channelMentionLens :: Lens' ChannelNotifyProps Bool
channelMentionLens :: (Bool -> f Bool) -> ChannelNotifyProps -> f ChannelNotifyProps
channelMentionLens = (ChannelNotifyProps -> Bool)
-> (ChannelNotifyProps -> Bool -> ChannelNotifyProps)
-> Lens ChannelNotifyProps ChannelNotifyProps Bool Bool
forall s a b t. (s -> a) -> (s -> b -> t) -> Lens s t a b
lens (\ChannelNotifyProps
props -> ChannelNotifyProps
propsChannelNotifyProps
-> Getting (WithDefault Bool) ChannelNotifyProps (WithDefault Bool)
-> WithDefault Bool
forall s a. s -> Getting a s a -> a
^.Getting (WithDefault Bool) ChannelNotifyProps (WithDefault Bool)
Lens' ChannelNotifyProps (WithDefault Bool)
channelNotifyPropsIgnoreChannelMentionsL WithDefault Bool -> WithDefault Bool -> Bool
forall a. Eq a => a -> a -> Bool
== Bool -> WithDefault Bool
forall a. a -> WithDefault a
IsValue Bool
True)
                     (\ChannelNotifyProps
props Bool
ignoreChannelMentions ->
                          ChannelNotifyProps
props { channelNotifyPropsIgnoreChannelMentions :: WithDefault Bool
channelNotifyPropsIgnoreChannelMentions = if Bool
ignoreChannelMentions
                                                                            then Bool -> WithDefault Bool
forall a. a -> WithDefault a
IsValue Bool
True
                                                                            else WithDefault Bool
forall a. WithDefault a
Default
                                })

notifyOptionName :: NotifyOption -> Text
notifyOptionName :: NotifyOption -> Text
notifyOptionName NotifyOption
NotifyOptionAll = Text
"All activity"
notifyOptionName NotifyOption
NotifyOptionMention = Text
"Mentions"
notifyOptionName NotifyOption
NotifyOptionNone = Text
"Never"

mkNotifyButtons :: ((WithDefault NotifyOption) -> Name)
                -> Lens' ChannelNotifyProps (WithDefault NotifyOption)
                -> NotifyOption
                -> ChannelNotifyProps
                -> FormFieldState ChannelNotifyProps e Name
mkNotifyButtons :: (WithDefault NotifyOption -> Name)
-> Lens' ChannelNotifyProps (WithDefault NotifyOption)
-> NotifyOption
-> ChannelNotifyProps
-> FormFieldState ChannelNotifyProps e Name
mkNotifyButtons WithDefault NotifyOption -> Name
mkName Lens' ChannelNotifyProps (WithDefault NotifyOption)
l NotifyOption
globalDefault =
    let optTuple :: NotifyOption -> (WithDefault NotifyOption, Name, Text)
optTuple NotifyOption
opt = (NotifyOption -> WithDefault NotifyOption
forall a. a -> WithDefault a
IsValue NotifyOption
opt, WithDefault NotifyOption -> Name
mkName (WithDefault NotifyOption -> Name)
-> WithDefault NotifyOption -> Name
forall a b. (a -> b) -> a -> b
$ NotifyOption -> WithDefault NotifyOption
forall a. a -> WithDefault a
IsValue NotifyOption
opt, NotifyOption -> Text
notifyOptionName NotifyOption
opt)
        defaultField :: (WithDefault a, Name, Text)
defaultField = (WithDefault a
forall a. WithDefault a
Default, WithDefault NotifyOption -> Name
mkName WithDefault NotifyOption
forall a. WithDefault a
Default, Text
"Global default (" Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> NotifyOption -> Text
notifyOptionName NotifyOption
globalDefault Text -> Text -> Text
forall a. Semigroup a => a -> a -> a
<> Text
")")
        nonDefault :: [(WithDefault NotifyOption, Name, Text)]
nonDefault = NotifyOption -> (WithDefault NotifyOption, Name, Text)
optTuple (NotifyOption -> (WithDefault NotifyOption, Name, Text))
-> [NotifyOption] -> [(WithDefault NotifyOption, Name, Text)]
forall (f :: * -> *) a b. Functor f => (a -> b) -> f a -> f b
<$> [ NotifyOption
NotifyOptionAll
                                  , NotifyOption
NotifyOptionMention
                                  , NotifyOption
NotifyOptionNone
                                  ]
    in Lens' ChannelNotifyProps (WithDefault NotifyOption)
-> [(WithDefault NotifyOption, Name, Text)]
-> ChannelNotifyProps
-> FormFieldState ChannelNotifyProps e Name
forall n a s e.
(Ord n, Show n, Eq a) =>
Lens' s a -> [(a, n, Text)] -> s -> FormFieldState s e n
radioField Lens' ChannelNotifyProps (WithDefault NotifyOption)
l ((WithDefault NotifyOption, Name, Text)
forall a. (WithDefault a, Name, Text)
defaultField (WithDefault NotifyOption, Name, Text)
-> [(WithDefault NotifyOption, Name, Text)]
-> [(WithDefault NotifyOption, Name, Text)]
forall a. a -> [a] -> [a]
: [(WithDefault NotifyOption, Name, Text)]
nonDefault)

notifyPrefsForm :: TeamId -> UserNotifyProps -> ChannelNotifyProps -> Form ChannelNotifyProps e Name
notifyPrefsForm :: TeamId
-> UserNotifyProps
-> ChannelNotifyProps
-> Form ChannelNotifyProps e Name
notifyPrefsForm TeamId
tId UserNotifyProps
globalDefaults =
    [ChannelNotifyProps -> FormFieldState ChannelNotifyProps e Name]
-> ChannelNotifyProps -> Form ChannelNotifyProps e Name
forall s e n. [s -> FormFieldState s e n] -> s -> Form s e n
newForm [ Lens ChannelNotifyProps ChannelNotifyProps Bool Bool
-> Name
-> Text
-> ChannelNotifyProps
-> FormFieldState ChannelNotifyProps e Name
forall n s e.
(Ord n, Show n) =>
Lens' s Bool -> n -> Text -> s -> FormFieldState s e n
checkboxField Lens ChannelNotifyProps ChannelNotifyProps Bool Bool
muteLens (TeamId -> Name
MuteToggleField TeamId
tId) Text
"Mute channel"
            , (Padding -> Widget Name -> Widget Name
forall n. Padding -> Widget n -> Widget n
padTop (Padding -> Widget Name -> Widget Name)
-> Padding -> Widget Name -> Widget Name
forall a b. (a -> b) -> a -> b
$ Int -> Padding
Pad Int
1) (Widget Name -> Widget Name)
-> (ChannelNotifyProps -> FormFieldState ChannelNotifyProps e Name)
-> ChannelNotifyProps
-> FormFieldState ChannelNotifyProps e Name
forall n s e.
(Widget n -> Widget n)
-> (s -> FormFieldState s e n) -> s -> FormFieldState s e n
@@= Lens ChannelNotifyProps ChannelNotifyProps Bool Bool
-> Name
-> Text
-> ChannelNotifyProps
-> FormFieldState ChannelNotifyProps e Name
forall n s e.
(Ord n, Show n) =>
Lens' s Bool -> n -> Text -> s -> FormFieldState s e n
checkboxField Lens ChannelNotifyProps ChannelNotifyProps Bool Bool
channelMentionLens (TeamId -> Name
ChannelMentionsField TeamId
tId) Text
"Ignore channel mentions"
            , String -> Widget Name -> Widget Name
forall n. String -> Widget n -> Widget n
radioStyle String
"Desktop notifications" (Widget Name -> Widget Name)
-> (ChannelNotifyProps -> FormFieldState ChannelNotifyProps e Name)
-> ChannelNotifyProps
-> FormFieldState ChannelNotifyProps e Name
forall n s e.
(Widget n -> Widget n)
-> (s -> FormFieldState s e n) -> s -> FormFieldState s e n
@@=
                (WithDefault NotifyOption -> Name)
-> Lens' ChannelNotifyProps (WithDefault NotifyOption)
-> NotifyOption
-> ChannelNotifyProps
-> FormFieldState ChannelNotifyProps e Name
forall e.
(WithDefault NotifyOption -> Name)
-> Lens' ChannelNotifyProps (WithDefault NotifyOption)
-> NotifyOption
-> ChannelNotifyProps
-> FormFieldState ChannelNotifyProps e Name
mkNotifyButtons (TeamId -> WithDefault NotifyOption -> Name
DesktopNotificationsField TeamId
tId) Lens' ChannelNotifyProps (WithDefault NotifyOption)
channelNotifyPropsDesktopL (UserNotifyProps -> NotifyOption
userNotifyPropsDesktop UserNotifyProps
globalDefaults)
            , String -> Widget Name -> Widget Name
forall n. String -> Widget n -> Widget n
radioStyle String
"Push notifications" (Widget Name -> Widget Name)
-> (ChannelNotifyProps -> FormFieldState ChannelNotifyProps e Name)
-> ChannelNotifyProps
-> FormFieldState ChannelNotifyProps e Name
forall n s e.
(Widget n -> Widget n)
-> (s -> FormFieldState s e n) -> s -> FormFieldState s e n
@@=
                (WithDefault NotifyOption -> Name)
-> Lens' ChannelNotifyProps (WithDefault NotifyOption)
-> NotifyOption
-> ChannelNotifyProps
-> FormFieldState ChannelNotifyProps e Name
forall e.
(WithDefault NotifyOption -> Name)
-> Lens' ChannelNotifyProps (WithDefault NotifyOption)
-> NotifyOption
-> ChannelNotifyProps
-> FormFieldState ChannelNotifyProps e Name
mkNotifyButtons (TeamId -> WithDefault NotifyOption -> Name
PushNotificationsField TeamId
tId) Lens' ChannelNotifyProps (WithDefault NotifyOption)
channelNotifyPropsPushL (UserNotifyProps -> NotifyOption
userNotifyPropsPush UserNotifyProps
globalDefaults)
            ]
    where radioStyle :: String -> Widget n -> Widget n
radioStyle String
label = (Padding -> Widget n -> Widget n
forall n. Padding -> Widget n -> Widget n
padTop (Padding -> Widget n -> Widget n)
-> Padding -> Widget n -> Widget n
forall a b. (a -> b) -> a -> b
$ Int -> Padding
Pad Int
1 ) (Widget n -> Widget n)
-> (Widget n -> Widget n) -> Widget n -> Widget n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (String -> Widget n
forall n. String -> Widget n
str String
label Widget n -> Widget n -> Widget n
forall n. Widget n -> Widget n -> Widget n
<=>) (Widget n -> Widget n)
-> (Widget n -> Widget n) -> Widget n -> Widget n
forall b c a. (b -> c) -> (a -> b) -> a -> c
. (Padding -> Widget n -> Widget n
forall n. Padding -> Widget n -> Widget n
padLeft (Padding -> Widget n -> Widget n)
-> Padding -> Widget n -> Widget n
forall a b. (a -> b) -> a -> b
$ Int -> Padding
Pad Int
1)

enterEditNotifyPrefsMode :: TeamId -> MH ()
enterEditNotifyPrefsMode :: TeamId -> MH ()
enterEditNotifyPrefsMode TeamId
tId =
    TeamId -> (ChannelId -> ClientChannel -> MH ()) -> MH ()
withCurrentChannel TeamId
tId ((ChannelId -> ClientChannel -> MH ()) -> MH ())
-> (ChannelId -> ClientChannel -> MH ()) -> MH ()
forall a b. (a -> b) -> a -> b
$ \ChannelId
_ ClientChannel
chan -> do
        case ClientChannel
chanClientChannel -> Getting Type ClientChannel Type -> Type
forall s a. s -> Getting a s a -> a
^.(ChannelInfo -> Const Type ChannelInfo)
-> ClientChannel -> Const Type ClientChannel
Lens' ClientChannel ChannelInfo
ccInfo((ChannelInfo -> Const Type ChannelInfo)
 -> ClientChannel -> Const Type ClientChannel)
-> ((Type -> Const Type Type)
    -> ChannelInfo -> Const Type ChannelInfo)
-> Getting Type ClientChannel Type
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Type -> Const Type Type) -> ChannelInfo -> Const Type ChannelInfo
Lens' ChannelInfo Type
cdType of
          Type
Direct -> MHError -> MH ()
mhError (MHError -> MH ()) -> MHError -> MH ()
forall a b. (a -> b) -> a -> b
$ Text -> MHError
GenericError Text
"Cannot open notification preferences for DM channel."
          Type
_ -> do
            let props :: ChannelNotifyProps
props = ClientChannel
chanClientChannel
-> Getting ChannelNotifyProps ClientChannel ChannelNotifyProps
-> ChannelNotifyProps
forall s a. s -> Getting a s a -> a
^.(ChannelInfo -> Const ChannelNotifyProps ChannelInfo)
-> ClientChannel -> Const ChannelNotifyProps ClientChannel
Lens' ClientChannel ChannelInfo
ccInfo((ChannelInfo -> Const ChannelNotifyProps ChannelInfo)
 -> ClientChannel -> Const ChannelNotifyProps ClientChannel)
-> ((ChannelNotifyProps
     -> Const ChannelNotifyProps ChannelNotifyProps)
    -> ChannelInfo -> Const ChannelNotifyProps ChannelInfo)
-> Getting ChannelNotifyProps ClientChannel ChannelNotifyProps
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(ChannelNotifyProps -> Const ChannelNotifyProps ChannelNotifyProps)
-> ChannelInfo -> Const ChannelNotifyProps ChannelInfo
Lens' ChannelInfo ChannelNotifyProps
cdNotifyProps
            User
user <- Getting User ChatState User -> MH User
forall s (m :: * -> *) a. MonadState s m => Getting a s a -> m a
use Getting User ChatState User
Lens' ChatState User
csMe
            TeamId -> Lens' ChatState TeamState
csTeam(TeamId
tId)((TeamState -> Identity TeamState)
 -> ChatState -> Identity ChatState)
-> ((Maybe (Form ChannelNotifyProps MHEvent Name)
     -> Identity (Maybe (Form ChannelNotifyProps MHEvent Name)))
    -> TeamState -> Identity TeamState)
-> (Maybe (Form ChannelNotifyProps MHEvent Name)
    -> Identity (Maybe (Form ChannelNotifyProps MHEvent Name)))
-> ChatState
-> Identity ChatState
forall b c a. (b -> c) -> (a -> b) -> a -> c
.(Maybe (Form ChannelNotifyProps MHEvent Name)
 -> Identity (Maybe (Form ChannelNotifyProps MHEvent Name)))
-> TeamState -> Identity TeamState
Lens' TeamState (Maybe (Form ChannelNotifyProps MHEvent Name))
tsNotifyPrefs ((Maybe (Form ChannelNotifyProps MHEvent Name)
  -> Identity (Maybe (Form ChannelNotifyProps MHEvent Name)))
 -> ChatState -> Identity ChatState)
-> Maybe (Form ChannelNotifyProps MHEvent Name) -> MH ()
forall s (m :: * -> *) a b.
MonadState s m =>
ASetter s s a b -> b -> m ()
.= (Form ChannelNotifyProps MHEvent Name
-> Maybe (Form ChannelNotifyProps MHEvent Name)
forall a. a -> Maybe a
Just (TeamId
-> UserNotifyProps
-> ChannelNotifyProps
-> Form ChannelNotifyProps MHEvent Name
forall e.
TeamId
-> UserNotifyProps
-> ChannelNotifyProps
-> Form ChannelNotifyProps e Name
notifyPrefsForm TeamId
tId (User -> UserNotifyProps
userNotifyProps User
user) ChannelNotifyProps
props))
            TeamId -> Mode -> MH ()
pushMode TeamId
tId Mode
EditNotifyPrefs

exitEditNotifyPrefsMode :: TeamId -> MH ()
exitEditNotifyPrefsMode :: TeamId -> MH ()
exitEditNotifyPrefsMode = TeamId -> MH ()
popMode