This commit is contained in:
Thomas Forgione 2022-02-05 21:05:41 +01:00
父節點 a3fb7dd5e4
當前提交 312f6e3c72
共有 13 個檔案被更改,包括 24947 行新增5780 行删除

1
.gitignore vendored
查看文件

@ -1 +1,2 @@
elm-stuff
target

394
Cargo.lock generated Normal file
查看文件

@ -0,0 +1,394 @@
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 3
[[package]]
name = "atk-sys"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f530e4af131d94cc4fa15c5c9d0348f0ef28bac64ba660b6b2a1cf2605dedfce"
dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps",
]
[[package]]
name = "bitflags"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
[[package]]
name = "boxfnonce"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5988cb1d626264ac94100be357308f29ff7cbdd3b36bda27f450a4ee3f713426"
[[package]]
name = "cairo-sys-rs"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "2ed2639b9ad5f1d6efa76de95558e11339e7318426d84ac4890b86c03e828ca7"
dependencies = [
"libc",
"system-deps",
]
[[package]]
name = "cc"
version = "1.0.72"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "22a9137b95ea06864e018375b72adfb7db6e6f68cfc8df5a04d00288050485ee"
[[package]]
name = "elmojinput"
version = "0.1.0"
dependencies = [
"web-view",
]
[[package]]
name = "gdk-pixbuf-sys"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3bfe468a7f43e97b8d193a762b6c5cf67a7d36cacbc0b9291dbcae24bfea1e8f"
dependencies = [
"gio-sys",
"glib-sys",
"gobject-sys",
"libc",
"system-deps",
]
[[package]]
name = "gdk-sys"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0a9653cfc500fd268015b1ac055ddbc3df7a5c9ea3f4ccef147b3957bd140d69"
dependencies = [
"cairo-sys-rs",
"gdk-pixbuf-sys",
"gio-sys",
"glib-sys",
"gobject-sys",
"libc",
"pango-sys",
"pkg-config",
"system-deps",
]
[[package]]
name = "gio-sys"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5e24fb752f8f5d2cf6bbc2c606fd2bc989c81c5e2fe321ab974d54f8b6344eac"
dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps",
"winapi",
]
[[package]]
name = "glib-sys"
version = "0.10.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7e9b997a66e9a23d073f2b1abb4dbfc3925e0b8952f67efd8d9b6e168e4cdc1"
dependencies = [
"libc",
"system-deps",
]
[[package]]
name = "gobject-sys"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "952133b60c318a62bf82ee75b93acc7e84028a093e06b9e27981c2b6fe68218c"
dependencies = [
"glib-sys",
"libc",
"system-deps",
]
[[package]]
name = "gtk-sys"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89acda6f084863307d948ba64a4b1ef674e8527dddab147ee4cdcc194c880457"
dependencies = [
"atk-sys",
"cairo-sys-rs",
"gdk-pixbuf-sys",
"gdk-sys",
"gio-sys",
"glib-sys",
"gobject-sys",
"libc",
"pango-sys",
"system-deps",
]
[[package]]
name = "heck"
version = "0.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6d621efb26863f0e9924c6ac577e8275e5e6b77455db64ffa6c65c904e9e132c"
dependencies = [
"unicode-segmentation",
]
[[package]]
name = "javascriptcore-rs-sys"
version = "0.2.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3f46ada8a08dcd75a10afae872fbfb51275df4a8ae0d46b8cc7c708f08dd2998"
dependencies = [
"libc",
]
[[package]]
name = "libc"
version = "0.2.117"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "e74d72e0f9b65b5b4ca49a346af3976df0f9c61d550727f349ecd559f251a26c"
[[package]]
name = "pango-sys"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "24d2650c8b62d116c020abd0cea26a4ed96526afda89b1c4ea567131fdefc890"
dependencies = [
"glib-sys",
"gobject-sys",
"libc",
"system-deps",
]
[[package]]
name = "pkg-config"
version = "0.3.24"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "58893f751c9b0412871a09abd62ecd2a00298c6c83befa223ef98c52aef40cbe"
[[package]]
name = "proc-macro2"
version = "1.0.36"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c7342d5883fbccae1cc37a2353b09c87c9b0f3afd73f5fb9bba687a1f733b029"
dependencies = [
"unicode-xid",
]
[[package]]
name = "quote"
version = "1.0.15"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "864d3e96a899863136fc6e99f3d7cae289dafe43bf2c5ac19b70df7210c0a145"
dependencies = [
"proc-macro2",
]
[[package]]
name = "serde"
version = "1.0.136"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ce31e24b01e1e524df96f1c2fdd054405f8d7376249a5110886fb4b658484789"
[[package]]
name = "soup-sys"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c3c7adf08565630bbb71f955f11f8a68464817ded2703a3549747c235b58a13e"
dependencies = [
"bitflags",
"gio-sys",
"glib-sys",
"gobject-sys",
"libc",
"pkg-config",
"system-deps",
]
[[package]]
name = "strum"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "57bd81eb48f4c437cadc685403cad539345bf703d78e63707418431cecd4522b"
[[package]]
name = "strum_macros"
version = "0.18.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87c85aa3f8ea653bfd3ddf25f7ee357ee4d204731f6aa9ad04002306f6e2774c"
dependencies = [
"heck",
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "syn"
version = "1.0.86"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8a65b3f4ffa0092e9887669db0eae07941f023991ab58ea44da8fe8e2d511c6b"
dependencies = [
"proc-macro2",
"quote",
"unicode-xid",
]
[[package]]
name = "system-deps"
version = "1.3.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0f3ecc17269a19353b3558b313bba738b25d82993e30d62a18406a24aba4649b"
dependencies = [
"heck",
"pkg-config",
"strum",
"strum_macros",
"thiserror",
"toml",
"version-compare",
]
[[package]]
name = "thiserror"
version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "854babe52e4df1653706b98fcfc05843010039b406875930a70e4d9644e5c417"
dependencies = [
"thiserror-impl",
]
[[package]]
name = "thiserror-impl"
version = "1.0.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "aa32fd3f627f367fe16f893e2597ae3c05020f8bba2666a4e6ea73d377e5714b"
dependencies = [
"proc-macro2",
"quote",
"syn",
]
[[package]]
name = "tinyfiledialogs"
version = "3.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "adc577626a3c26e4e1d470dbe5fe33d6fabc14e57114cb377acdb4da1a17dde9"
dependencies = [
"cc",
"libc",
]
[[package]]
name = "toml"
version = "0.5.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a31142970826733df8241ef35dc040ef98c679ab14d7c3e54d827099b3acecaa"
dependencies = [
"serde",
]
[[package]]
name = "unicode-segmentation"
version = "1.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8895849a949e7845e06bd6dc1aa51731a103c42707010a5b591c0038fb73385b"
[[package]]
name = "unicode-xid"
version = "0.2.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ccb82d61f80a663efe1f787a51b16b5a51e3314d6ac365b08639f52387b33f3"
[[package]]
name = "urlencoding"
version = "1.3.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5a1f0175e03a0973cf4afd476bef05c26e228520400eb1fd473ad417b1c00ffb"
[[package]]
name = "version-compare"
version = "0.0.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d63556a25bae6ea31b52e640d7c41d1ab27faba4ccb600013837a3d0b3994ca1"
[[package]]
name = "web-view"
version = "0.7.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ee1da6aa5f232e7a4f17ae4549772d2e35d0f4ade03e7527b25c4c0b00abafea"
dependencies = [
"boxfnonce",
"tinyfiledialogs",
"urlencoding",
"webview-sys",
]
[[package]]
name = "webkit2gtk-sys"
version = "0.12.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "389e5138c85a0d111b9bda05b59efa8562315e1d657d72451410e12c858f0619"
dependencies = [
"atk-sys",
"bitflags",
"cairo-sys-rs",
"gdk-pixbuf-sys",
"gdk-sys",
"gio-sys",
"glib-sys",
"gobject-sys",
"gtk-sys",
"javascriptcore-rs-sys",
"libc",
"pango-sys",
"pkg-config",
"soup-sys",
]
[[package]]
name = "webview-sys"
version = "0.6.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0001f025c1425ffe36270a81cb091eade87dd8d29ac773735ae47e1a8c8066c9"
dependencies = [
"cc",
"gdk-sys",
"gio-sys",
"glib-sys",
"gobject-sys",
"gtk-sys",
"javascriptcore-rs-sys",
"libc",
"pkg-config",
"webkit2gtk-sys",
]
[[package]]
name = "winapi"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419"
dependencies = [
"winapi-i686-pc-windows-gnu",
"winapi-x86_64-pc-windows-gnu",
]
[[package]]
name = "winapi-i686-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6"
[[package]]
name = "winapi-x86_64-pc-windows-gnu"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f"

9
Cargo.toml Normal file
查看文件

@ -0,0 +1,9 @@
[package]
name = "elmojinput"
version = "0.1.0"
edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
web-view = "0.7.3"

查看文件

@ -12,17 +12,23 @@ endif
BUILD_DIR=js
dev: js/main.js
release: js/main.min.js
dev: target/debug/elmojinput
release: target/release/elmojinput
js/main.js: src/**
$(ELM) make src/Main.elm --output $(BUILD_DIR)/main.js
js/main.js: elm/**
$(ELM) make elm/Main.elm --output $(BUILD_DIR)/main.js
js/main.min.js: js/main.tmp.js
@$(UGLIFYJS) $(BUILD_DIR)/main.tmp.js --compress 'pure_funcs="F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9",pure_getters,keep_fargs=false,unsafe_comps,unsafe' | $(UGLIFYJS) --mangle > $(BUILD_DIR)/main.min.js
js/main.tmp.js: src/**
@$(ELM) make src/Main.elm --optimize --output $(BUILD_DIR)/main.tmp.js
js/main.tmp.js: elm/**
@$(ELM) make elm/Main.elm --optimize --output $(BUILD_DIR)/main.tmp.js
target/debug/elmojinput: js/main.js src/**
cargo build
target/release/elmojinput: js/main.min.js src/**
cargo build --release
clean:
@rm -rf $(BUILD_DIR)/{main.js,main.min.js}

查看文件

@ -1,18 +1,19 @@
{
"type": "application",
"source-directories": [
"src"
"elm"
],
"elm-version": "0.19.1",
"dependencies": {
"direct": {
"dasch/levenshtein": "1.0.3",
"elm/browser": "1.0.2",
"elm/core": "1.0.5",
"elm/html": "1.0.0",
"elm/json": "1.1.3",
"mdgriffith/elm-ui": "1.1.8"
},
"indirect": {
"elm/json": "1.1.3",
"elm/time": "1.0.0",
"elm/url": "1.0.0",
"elm/virtual-dom": "1.0.2"

238
elm/Main.elm Normal file
查看文件

@ -0,0 +1,238 @@
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
import Html.Events
import Json.Decode as Decode
import Levenshtein
main =
Browser.element
{ init = init
, update = update
, subscriptions = \_ -> Sub.none
, view = view
}
-- MODEL --
type Model
= Search String
| Category Emoji.Category
modelCategory : Model -> Maybe Emoji.Category
modelCategory model =
case model of
Category c ->
Just c
_ ->
Nothing
modelSearch : Model -> Maybe String
modelSearch model =
case model of
Search s ->
Just s
_ ->
Nothing
modelEmojis : Model -> List Emoji.Emoji
modelEmojis model =
case model of
Category c ->
Emoji.getEmojis c
Search s ->
Emoji.categories
|> List.concatMap Emoji.getEmojis
|> List.map (\x -> ( x, minimum ( Levenshtein.distance s x.name, List.map (\v -> Levenshtein.distance s v + 1) x.tags ) ))
|> List.sortBy Tuple.second
|> List.map Tuple.first
init : () -> ( Model, Cmd Msg )
init _ =
( Category Emoji.Recent, Cmd.none )
type Msg
= CategoryClicked Emoji.Category
| SearchChanged String
| EnterPressed
| Copy String
-- UPDATE --
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
CategoryClicked category ->
( Category category, Cmd.none )
SearchChanged search ->
( Search search, Cmd.none )
EnterPressed ->
( model
, List.head (modelEmojis model)
|> Maybe.map .unicode
|> Maybe.map copy
|> Maybe.withDefault Cmd.none
)
Copy c ->
( model, copy c )
-- VIEW --
view : Model -> Html.Html Msg
view model =
[ header model, panel (modelEmojis model) ]
|> Element.column [ Element.width (Element.px 512), Element.height (Element.px 512) ]
|> Element.layout []
header : Model -> Element Msg
header model =
Element.row [ Element.width Element.fill, Element.padding 5, Element.spacing 10 ]
[ Element.row [ Element.width Element.fill, Element.spacing 10 ]
(Emoji.categories
|> List.map
(\x ->
Input.button
[ Element.padding 5
, Border.color (Element.rgb255 0 0 0)
, if modelCategory model == Just x then
Border.width 5
else
Border.width 1
, Border.rounded 5
]
{ label = Element.el [] (emoji (Emoji.categoryEmoji x))
, onPress = Just (CategoryClicked x)
}
)
)
, Input.text
[ Element.width Element.fill
, Input.focusedOnLoad
, onEnter EnterPressed
]
{ label = Input.labelHidden "input"
, onChange = SearchChanged
, placeholder = Just (Input.placeholder [] (Element.text "search"))
, text = modelSearch model |> Maybe.withDefault ""
}
]
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
-- UTILS --
minimum : ( comparable, List comparable ) -> comparable
minimum ( h, t ) =
case List.minimum t of
Nothing ->
h
Just v ->
min h v
maximum : ( comparable, List comparable ) -> comparable
maximum ( h, t ) =
case List.maximum t of
Nothing ->
h
Just v ->
max h v
onEnter : msg -> Element.Attribute msg
onEnter msg =
Element.htmlAttribute
(Html.Events.on "keyup"
(Decode.field "key" Decode.string
|> Decode.andThen
(\key ->
if key == "Enter" then
Decode.succeed msg
else
Decode.fail "Not the enter key"
)
)
)

查看文件

@ -22,6 +22,9 @@
el.select();
document.execCommand('copy');
document.body.removeChild(el);
window.webkit.messageHandlers.external.postMessage(str);
// window.external.invoke("test_one");
});
</script>
</body>

12603
js/main.js

檔案差異因為檔案過大而無法顯示 載入差異

1
js/main.min.js vendored Normal file

檔案差異因為一行或多行太長而無法顯示

17289
js/main.tmp.js Normal file

檔案差異因為檔案過大而無法顯示 載入差異

查看文件

@ -1,127 +0,0 @@
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

39
src/main.rs Normal file
查看文件

@ -0,0 +1,39 @@
use std::io::Write;
use std::process::{exit, Command, Stdio};
use web_view::*;
fn main() {
#[cfg(debug_assertions)]
let js = include_str!("../../elmoji/js/main.js");
#[cfg(not(debug_assertions))]
let js = include_str!("../../elmoji/js/main.min.js");
let html_content = include_str!("../../elmoji/index.html").replace(
"<script src=\"js/main.js\"></script>",
&format!("<script>{}</script>", js),
);
web_view::builder()
.title("Elmojinput")
.content(Content::Html(html_content))
.size(512, 512)
.resizable(false)
.debug(true)
.user_data(())
.invoke_handler(|_webview, arg| {
let mut child = Command::new("xclip")
.arg("-selection")
.arg("clipboard")
.stdin(Stdio::piped())
.stdout(Stdio::piped())
.spawn()
.unwrap();
let stdin = child.stdin.as_mut().unwrap();
stdin.write_all(arg.as_bytes()).unwrap();
exit(0);
})
.run()
.unwrap();
}