port module Main exposing (..) import Browser import Element exposing (Element) import Element.Border as Border import Element.Input as Input import Emoji import Html import Html.Attributes main = Browser.element { init = init , update = update , subscriptions = \_ -> Sub.none , view = view } -- MODEL -- type alias Model = { category : Emoji.Category } init : () -> ( Model, Cmd Msg ) init _ = ( { category = Emoji.Recent }, Cmd.none ) type Msg = CategoryClicked Emoji.Category | Copy String -- UPDATE -- update : Msg -> Model -> ( Model, Cmd Msg ) update msg model = case msg of CategoryClicked category -> ( { model | category = category }, Cmd.none ) Copy c -> ( model, copy c ) -- VIEW -- view : Model -> Html.Html Msg view model = Element.layout [] (Element.column [ Element.width (Element.px 512), Element.height (Element.px 512) ] [ header, panel (Emoji.getEmojis model.category) ] ) header : Element Msg header = Element.row [ Element.width Element.fill, Element.padding 5, Element.spacing 10 ] (Emoji.categories |> List.map (\x -> Input.button [ Element.padding 5, Border.color (Element.rgb255 0 0 0), Border.width 1, Border.rounded 5 ] { label = Element.el [] (emoji (Emoji.categoryEmoji x)) , onPress = Just (CategoryClicked x) } ) ) panel : List Emoji.Emoji -> Element Msg panel em = em |> regroup 10 |> List.map (\x -> List.map maybeEmoji x) |> List.map (Element.row [ Element.width Element.fill ]) |> Element.column [ Element.width (Element.px 512), Element.height (Element.px 512), Element.scrollbarY ] emoji : Emoji.Emoji -> Element Msg emoji e = Input.button [ Element.htmlAttribute (Html.Attributes.title e.name), Element.centerX, Element.centerY ] { label = Element.text e.unicode, onPress = Just (Copy e.unicode) } maybeEmoji : Maybe Emoji.Emoji -> Element Msg maybeEmoji e = Element.el [ Element.width Element.fill, Element.padding 10 ] (Maybe.map emoji e |> Maybe.withDefault Element.none) regroup : Int -> List Emoji.Emoji -> List (List (Maybe Emoji.Emoji)) regroup num input = List.reverse (regroupAux [] [] num input) regroupAux : List (List (Maybe Emoji.Emoji)) -> List (Maybe Emoji.Emoji) -> Int -> List Emoji.Emoji -> List (List (Maybe Emoji.Emoji)) regroupAux currentTotal currentPart num input = case input of [] -> if List.length currentPart < num then regroupAux currentTotal (Nothing :: currentPart) num [] else List.reverse currentPart :: currentTotal h :: t -> if List.length currentPart >= num then regroupAux (List.reverse currentPart :: currentTotal) [ Just h ] num t else regroupAux currentTotal (Just h :: currentPart) num t -- PORTS -- port copy : String -> Cmd msg