From 8181ef2dfaba6bc9c332b0e2bc8e755436134135 Mon Sep 17 00:00:00 2001 From: Bram Date: Tue, 5 Nov 2024 10:28:10 +0100 Subject: [PATCH] Add initial log viewer --- src/Items/Introduction.elm | 20 ++---- src/Items/LogViewer.elm | 49 +++++++++++++++ src/Layout.elm | 50 +++++++++++++-- src/Main.elm | 38 ++++++++--- src/Screen/Vault.elm | 125 ++++++++++++++++++++++++++++++++++--- 5 files changed, 244 insertions(+), 38 deletions(-) create mode 100644 src/Items/LogViewer.elm diff --git a/src/Items/Introduction.elm b/src/Items/Introduction.elm index c0dd2a3..c937ecb 100644 --- a/src/Items/Introduction.elm +++ b/src/Items/Introduction.elm @@ -3,6 +3,7 @@ module Items.Introduction exposing (..) import Color exposing (Color) import Element exposing (Element) import Element.Background +import Layout import Theme import Widget.Material.Typography @@ -31,9 +32,9 @@ view : } -> Element msg view data = - [ header "Martiplier" - , text "Martiplier (short for Matrix Plier) is a unique client. It doesn't let you browse rooms and have chat conversations." - , text "Instead, it offers you a more debug-like display of a user account. This helps when trying to do bulk operations, or to discover information about a client." + [ Layout.header "Martiplier" + , Layout.stdText "Martiplier (short for Matrix Plier) is a unique client. It doesn't let you browse rooms and have chat conversations." + , Layout.stdText "Instead, it offers you a more debug-like display of a user account. This helps when trying to do bulk operations, or to discover information about a client." ] |> Element.column [ Element.Background.color (Theme.toElmUiColor data.colorBackground) @@ -41,16 +42,3 @@ view data = , Element.spacing 20 , Element.width (Element.px data.width) ] - - -header : String -> Element msg -header = - Element.text - >> Element.el Widget.Material.Typography.h1 - >> List.singleton - >> Element.paragraph [] - - -text : String -> Element msg -text = - Element.text >> List.singleton >> Element.paragraph [] diff --git a/src/Items/LogViewer.elm b/src/Items/LogViewer.elm new file mode 100644 index 0000000..ad14545 --- /dev/null +++ b/src/Items/LogViewer.elm @@ -0,0 +1,49 @@ +module Items.LogViewer exposing (..) + +import Element exposing (Element) +import Element.Font + + + +-- MODEL +-- UPDATE +-- VIEW + + +viewRecent : + { height : Int + , logs : List { channel : String, content : String } + , width : Int + } + -> Element msg +viewRecent data = + let + channelWidth = + 90 + + contentWidth = + data.width - channelWidth + in + Element.table + [] + { data = data.logs + , columns = + [ { header = Element.el [ Element.Font.bold ] (Element.text "Channel") + , width = Element.px channelWidth + , view = .channel >> Element.text + } + , { header = Element.el [ Element.Font.bold ] (Element.text "Content") + , width = Element.px contentWidth + , view = .content >> String.replace "\n" " " >> stripText (contentWidth // 10) >> Element.text + } + ] + } + + +stripText : Int -> String -> String +stripText n text = + if String.length text < n then + text + + else + String.left (n - 3) text ++ "..." diff --git a/src/Layout.elm b/src/Layout.elm index 8bf6121..f9fbba0 100644 --- a/src/Layout.elm +++ b/src/Layout.elm @@ -4,6 +4,7 @@ module Layout exposing , iconAsElement, iconAsIcon , containedButton, outlinedButton, textButton , textInput, passwordInput + , header, stdText , itemWithSubtext , sideList , loadingIndicator @@ -43,6 +44,11 @@ beautiful Material design Elm webpage. @docs textInput, passwordInput +## Text + +@docs header, stdText + + ## Items in a list @docs itemWithSubtext @@ -61,13 +67,18 @@ beautiful Material design Elm webpage. import Color exposing (Color) import Element exposing (Element) +import Element.Background import Element.Events +import Element.Font import Element.Input +import Html.Attributes import Material.Icons.Types +import Theme import Widget import Widget.Customize as Customize import Widget.Icon exposing (Icon) import Widget.Material as Material +import Widget.Material.Typography {-| A contained button representing the most important action of a group. @@ -90,6 +101,14 @@ containedButton data = { text = data.text, icon = data.icon, onPress = data.onPress } +header : String -> Element msg +header = + Element.text + >> Element.el Widget.Material.Typography.h1 + >> List.singleton + >> Element.paragraph [] + + iconAsElement : { color : Color , height : Int @@ -232,24 +251,40 @@ sideIconBar data = buttonHeight = round (toFloat data.width * 1.618) + fontSize = + data.width // 6 + iconSize = - data.width // 2 + data.width * 3 // 5 in data.items |> List.map (\item -> [ item.icon { size = iconSize, color = data.colorText } + |> Element.el [ Element.centerX ] , Element.paragraph [] [ Element.text item.text ] ] - |> Element.column [ Element.centerX, Element.centerY ] + |> Element.column + [ Element.centerX + , Element.centerY + , Element.Font.bold + , Element.Font.center + , Element.Font.size fontSize + , Element.htmlAttribute (Html.Attributes.style "cursor" "pointer") + ] |> Element.el - [ Element.Events.onClick item.onPress - , Element.height (Element.px buttonHeight) + [ Element.centerY + , Element.Events.onClick item.onPress + , Element.height (Element.px data.width) , Element.width (Element.px data.width) ] + |> Element.el + [ Element.height (Element.px buttonHeight) + ] ) |> Element.column - [ Element.height (Element.px data.height) + [ Element.Background.color (Theme.toElmUiColor data.colorBackground) + , Element.height (Element.px data.height) , Element.scrollbarY , Element.width (Element.px data.width) ] @@ -271,6 +306,11 @@ sideList data = |> Element.el [ width data.width ] +stdText : String -> Element msg +stdText = + Element.text >> List.singleton >> Element.paragraph [] + + {-| A tab selector that always has an item selected. -} tab : diff --git a/src/Main.elm b/src/Main.elm index e80ed81..a4ee852 100644 --- a/src/Main.elm +++ b/src/Main.elm @@ -6,6 +6,7 @@ import Browser.Events import Element exposing (Element) import Element.Background import Element.Font +import Iddict import Items.VaultList as VaultList import Matrix import Recursion @@ -29,6 +30,10 @@ main = -- MODEL +type MatrixAction + = Sync + + type alias Model = { flavor : Theme.Flavor , height : Int @@ -37,13 +42,10 @@ type alias Model = } -type Screen - = ScreenWelcome WelcomeScreen.Model - | ScreenVault Vaults Int VaultScreen.Model - - type Msg - = OnScreenVault Int VaultScreen.Msg + = OnMatrix MatrixAction Int Matrix.Vault + | OnReturnHome Vaults + | OnScreenVault Int VaultScreen.Msg | OnScreenWelcome WelcomeScreen.Msg | OnSelectVault Vaults Int | OnVaultUpdate Int Matrix.VaultUpdate @@ -52,6 +54,11 @@ type Msg | SetFlavor Theme.Flavor +type Screen + = ScreenWelcome WelcomeScreen.Model + | ScreenVault Vaults Int VaultScreen.Model + + type alias Vaults = VaultList.Model @@ -81,6 +88,14 @@ init () = update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of + OnMatrix Sync i vault -> + ( model, Matrix.sync (OnVaultUpdate i) vault ) + + OnReturnHome vaults -> + ( { model | screen = ScreenWelcome (WelcomeScreen.fromVaults vaults) } + , Cmd.none + ) + OnScreenVault i m -> case model.screen of ScreenVault welcomeMdl j mdl -> @@ -206,16 +221,21 @@ viewScreen model = (\screen -> case screen of ScreenVault vaults i mdl -> - case VaultList.getVault i vaults of - Just vault -> + case Iddict.get i vaults of + Just block -> VaultScreen.view { colorBackground = colorBackground + , colorBackground2 = colorBackground2 + , colorMain = colorMain , colorText = colorText , height = model.height + , logs = block.logs , model = mdl + , onReturnToMenu = OnReturnHome vaults + , onSync = OnMatrix Sync i block.vault , onVaultUpdate = OnVaultUpdate i , toMsg = OnScreenVault i - , vault = vault + , vault = block.vault , width = model.width } |> Recursion.base diff --git a/src/Screen/Vault.elm b/src/Screen/Vault.elm index a4d39ba..0ab877b 100644 --- a/src/Screen/Vault.elm +++ b/src/Screen/Vault.elm @@ -2,6 +2,9 @@ module Screen.Vault exposing (..) import Color exposing (Color) import Element exposing (Element) +import Items.LogViewer as LogViewer +import Layout +import Material.Icons import Matrix @@ -10,16 +13,21 @@ import Matrix type alias Model = - () + Screen -type alias Msg = - () +type Msg + = GoToScreen Screen + + +type Screen + = Home + | Logs init : Model init = - () + Home @@ -27,10 +35,10 @@ init = update : Msg -> Model -> Model -update msg model = +update msg _ = case msg of - () -> - model + GoToScreen screen -> + screen @@ -39,9 +47,14 @@ update msg model = view : { colorBackground : Color + , colorBackground2 : Color + , colorMain : Color , colorText : Color , height : Int + , logs : List { channel : String, content : String } , model : Model + , onReturnToMenu : msg + , onSync : msg , onVaultUpdate : Matrix.VaultUpdate -> msg , toMsg : Msg -> msg , vault : Matrix.Vault @@ -49,4 +62,100 @@ view : } -> Element msg view data = - Element.none + Element.row + [ Element.height (Element.px data.height) + , Element.width (Element.px data.width) + ] + [ Layout.sideIconBar + { colorBackground = data.colorBackground2 + , colorText = data.colorText + , height = data.height + , items = + [ { icon = Layout.iconAsIcon Material.Icons.arrow_back + , onPress = data.onReturnToMenu + , text = "Return to menu" + } + , { icon = Layout.iconAsIcon Material.Icons.home + , onPress = data.toMsg (GoToScreen Home) + , text = "Home" + } + , { icon = Layout.iconAsIcon Material.Icons.inbox + , onPress = data.toMsg (GoToScreen Logs) + , text = "Logs" + } + ] + , width = 100 + } + , viewContent + { colorMain = data.colorMain + , colorText = data.colorText + , height = data.height + , logs = data.logs + , model = data.model + , onSync = data.onSync + , vault = data.vault + , width = data.width - 100 + } + ] + + +viewContent : + { colorMain : Color + , colorText : Color + , height : Int + , logs : List { channel : String, content : String } + , model : Model + , onSync : msg + , vault : Matrix.Vault + , width : Int + } + -> Element msg +viewContent data = + let + paddingSize = + 30 + in + Element.el [ Element.padding paddingSize ] + (case data.model of + Logs -> + LogViewer.viewRecent + { height = data.height - 2 * paddingSize + , logs = data.logs + , width = data.width - 2 * paddingSize + } + + Home -> + viewStartMenu + { colorMain = data.colorMain + , colorText = data.colorText + , height = data.height - 2 * paddingSize + , onSync = data.onSync + , width = data.width - 2 * paddingSize + } + ) + + +viewStartMenu : + { colorMain : Color + , colorText : Color + , height : Int + , onSync : msg + , width : Int + } + -> Element msg +viewStartMenu data = + Element.column + [ Element.height (Element.px data.height) + , Element.spacing 5 + , Element.width (Element.px data.width) + ] + [ Layout.header "Start Menu" + , Layout.stdText "The elm-matrix-sdk vault uses the /sync endpoint to get the latest updates. Make sure to run this function to get the latest information." + , Layout.containedButton + { buttonColor = data.colorMain + , clickColor = data.colorText + , icon = always Element.none + , onPress = Just data.onSync + , text = "SYNC" + } + ]