From 4cecb23001af30c1d5b33df5603ccdcba70b6e2a Mon Sep 17 00:00:00 2001 From: Craig Everett Date: Wed, 13 Nov 2024 12:26:19 +0900 Subject: [PATCH] Minor updates: - Improve layout of TX request GRIDS screen - Add clipboard copy option to mnemonic dialog - Silence a few old tell/2 calls - Refresh main sizer layout on gmc_gui:show/1 - Resize a few silly looking single-input dialogs --- ebin/clutch.app | 6 +- src/clutch.erl | 2 +- src/gmc_con.erl | 27 ++++---- src/gmc_grids.erl | 2 +- src/gmc_gui.erl | 152 ++++++++++++++++++++++++----------------- src/gmc_jt.erl | 1 + src/gmc_key_master.erl | 1 + src/gmc_sup.erl | 2 +- src/gmc_v.erl | 2 +- src/gmc_v_netman.erl | 4 +- src/gmc_v_wallman.erl | 4 +- zomp.meta | 10 +-- 12 files changed, 122 insertions(+), 91 deletions(-) diff --git a/ebin/clutch.app b/ebin/clutch.app index d2cfebc..7ca5678 100644 --- a/ebin/clutch.app +++ b/ebin/clutch.app @@ -3,6 +3,8 @@ {registered,[]}, {included_applications,[]}, {applications,[stdlib,kernel]}, - {vsn,"0.1.0"}, - {modules,[clutch,gmc_con,gmc_gui,gmc_jt,gmc_key_master,gmc_sup]}, + {vsn,"0.1.1"}, + {modules,[clutch,gmc_con,gmc_grids,gmc_gui,gmc_jt, + gmc_key_master,gmc_sup,gmc_v,gmc_v_netman, + gmc_v_wallman]}, {mod,{clutch,[]}}]}. diff --git a/src/clutch.erl b/src/clutch.erl index af49889..eccba9c 100644 --- a/src/clutch.erl +++ b/src/clutch.erl @@ -3,7 +3,7 @@ %%% @end -module(clutch). --vsn("0.1.0"). +-vsn("0.1.1"). -behavior(application). -author("Craig Everett "). -copyright("QPQ AG "). diff --git a/src/gmc_con.erl b/src/gmc_con.erl index 3e593ce..30d914b 100644 --- a/src/gmc_con.erl +++ b/src/gmc_con.erl @@ -5,7 +5,7 @@ %%% @end -module(gmc_con). --vsn("0.1.0"). +-vsn("0.1.1"). -author("Craig Everett "). -copyright("QPQ AG "). -license("GPL-3.0-or-later"). @@ -167,7 +167,7 @@ sign_tx(Request) -> Name :: string(), Seed :: string(), Encoding :: utf8 | base64 | base58, - Transform :: raw | {Algo, Yugeness}, + Transform :: {Algo, Yugeness}, Algo :: sha3 | sha2 | x_or | pbkdf2, Yugeness :: rand | non_neg_integer(). %% @doc @@ -542,16 +542,17 @@ do_grids(String) -> end. do_grids2({{sign, http}, URL}) -> - ok = tell("Making request to ~p", [URL]), + ok = log(info, "Making request to ~p", [URL]), case httpc:request(URL) of - {ok, {{_, 200, _}, _, JSON}} -> do_grids_sig(JSON, URL); - Error -> gmc_gui:trouble(Error) + {ok, {{_, 200, _}, _, JSON}} -> do_grids_sig(JSON, URL); + {error, socket_closed_remotely} -> tell("Yep, closed remotely."); + Error -> gmc_gui:trouble(Error) end; do_grids2(Instruction) -> tell("GRIDS: ~tp", [Instruction]). do_grids_sig(JSON, URL) -> - ok = tell("Received: ~p", [JSON]), + ok = log(info, "Received: ~p", [JSON]), case zj:decode(JSON) of {ok, GRIDS} -> do_grids_sig2(GRIDS#{"url" => URL}); Error -> gmc_gui:trouble(Error) @@ -586,8 +587,9 @@ do_sign_mess2(Request = #{"url" := URL}) -> "signature"], Response = zj:encode(maps:with(ResponseKeys, Request)), case httpc:request(post, {URL, [], "application/json", Response}, [], []) of - {ok, {{_, 200, _}, _, JSON}} -> log(info, "Signature posted: ~p", [JSON]); - Error -> gmc_gui:trouble(Error) + {ok, {{_, 200, _}, _, JSON}} -> log(info, "Signature posted: ~p", [JSON]); + {error, socket_closed_remotely} -> tell("Yep, closed remotely."); + Error -> gmc_gui:trouble(Error) end. @@ -645,8 +647,9 @@ do_sign_tx2(Request = #{"url" := URL}) -> "signed"], Response = zj:encode(maps:with(ResponseKeys, Request)), case httpc:request(post, {URL, [], "application/json", Response}, [], []) of - {ok, {{_, 200, _}, _, JSON}} -> log(info, "Signature posted: ~p", [JSON]); - Error -> gmc_gui:trouble(Error) + {ok, {{_, 200, _}, _, JSON}} -> log(info, "Signed TX posted: ~p", [JSON]); + {error, socket_closed_remotely} -> tell("Closed remotely."); + Error -> gmc_gui:trouble(Error) end. sign_tx_hash(Unsigned, PrivKey, NetworkID) -> @@ -795,9 +798,7 @@ transform({sha3, 256}) -> transform({sha2, 256}) -> fun(D) -> crypto:hash(sha256, D) end; transform({x_or, 256}) -> - fun t_xor/1; -transform(raw) -> - fun(D) -> D end. + fun t_xor/1. t_xor(Bin) -> t_xor(Bin, <<0:256>>). diff --git a/src/gmc_grids.erl b/src/gmc_grids.erl index e654850..7021b23 100644 --- a/src/gmc_grids.erl +++ b/src/gmc_grids.erl @@ -37,7 +37,7 @@ %%% @end -module(gmc_grids). --vsn("0.1.0"). +-vsn("0.1.1"). -author("Craig Everett "). -copyright("QPQ AG "). -license("GPL-3.0-or-later"). diff --git a/src/gmc_gui.erl b/src/gmc_gui.erl index 28b858a..e608a81 100644 --- a/src/gmc_gui.erl +++ b/src/gmc_gui.erl @@ -7,7 +7,7 @@ %%% @end -module(gmc_gui). --vsn("0.1.0"). +-vsn("0.1.1"). -author("Craig Everett "). -copyright("QPQ AG "). -license("GPL-3.0-or-later"). @@ -31,6 +31,7 @@ -record(s, {wx = none :: none | wx:wx_object(), frame = none :: none | wx:wx_object(), + sizer = none :: none | wx:wx_object(), lang = en :: en | jp, j = none :: none | fun(), prefs = #{} :: #{atom() := term()}, @@ -193,7 +194,7 @@ init(Prefs) -> ok = wxFrame:connect(Frame, close_window), true = wxFrame:show(Frame), ok = wxListBox:connect(Picker, command_listbox_selected), - State = #s{wx = Wx, frame = Frame, lang = Lang, j = J, prefs = Prefs, + State = #s{wx = Wx, frame = Frame, sizer = MainSz, lang = Lang, j = J, prefs = Prefs, accounts = [], picker = Picker, id = ID_W, @@ -381,8 +382,8 @@ set_node(State = #s{frame = Frame, j = J}) -> ok = wxDialog:setSizer(Dialog, Sizer), ok = wxBoxSizer:layout(Sizer), - ok = wxFrame:setSize(Dialog, {500, 200}), - ok = wxFrame:center(Dialog), + ok = wxDialog:setSize(Dialog, {500, 200}), + ok = wxDialog:center(Dialog), ok = wxStyledTextCtrl:setFocus(AddressTx), ok = @@ -448,8 +449,7 @@ make_key(State = #s{frame = Frame, j = J}) -> Transforms = ["SHA-3 (256)", "SHA-2 (256)", - "XOR", - "Direct Input (no transform)"], + "XOR"], TransformOptions = wxChoice:new(Dialog, ?wxID_ANY, [{choices, Transforms}]), ok = wxChoice:setSelection(TransformOptions, 0), @@ -491,8 +491,7 @@ make_key(State = #s{frame = Frame, j = J}) -> case wxChoice:getSelection(TransformOptions) of 0 -> {sha3, 256}; 1 -> {sha2, 256}; - 2 -> {x_or, 256}; - 3 -> raw + 2 -> {x_or, 256} end, gmc_con:make_key(Type, Size, Name, Seed, Encoding, Transform); ?wxID_CANCEL -> @@ -549,15 +548,21 @@ show_mnemonic(Selected, State = #s{frame = Frame, j = J, accounts = Accounts}) - MnemTx = wxTextCtrl:new(Dialog, ?wxID_ANY, Options), _ = wxStaticBoxSizer:add(MnemSz, MnemTx, zxw:flags(wide)), ButtSz = wxBoxSizer:new(?wxHORIZONTAL), - Affirm = wxButton:new(Dialog, ?wxID_OK), - _ = wxBoxSizer:add(ButtSz, Affirm, zxw:flags(wide)), + CloseB = wxButton:new(Dialog, ?wxID_CANCEL, [{label, J("Close")}]), + CopyB = wxButton:new(Dialog, ?wxID_OK, [{label, J("Copy to Clipboard")}]), + _ = wxBoxSizer:add(ButtSz, CloseB, zxw:flags(wide)), + _ = wxBoxSizer:add(ButtSz, CopyB, zxw:flags(wide)), _ = wxBoxSizer:add(Sizer, MnemSz, zxw:flags(wide)), _ = wxBoxSizer:add(Sizer, ButtSz, zxw:flags(base)), ok = wxDialog:setSizer(Dialog, Sizer), ok = wxBoxSizer:layout(Sizer), ok = wxFrame:center(Dialog), ok = wxStyledTextCtrl:setFocus(MnemTx), - ?wxID_OK = wxDialog:showModal(Dialog), + ok = + case wxDialog:showModal(Dialog) of + ?wxID_CANCEL -> ok; + ?wxID_OK -> copy_to_clipboard(Mnemonic) + end, ok = wxDialog:destroy(Dialog), State. @@ -584,10 +589,11 @@ rename_key(Selected, State = #s{frame = Frame, j = J, accounts = Accounts}) -> _ = wxBoxSizer:add(ButtSz, Affirm, zxw:flags(wide)), _ = wxBoxSizer:add(ButtSz, Cancel, zxw:flags(wide)), _ = wxBoxSizer:add(Sizer, NameSz, zxw:flags(base)), - _ = wxBoxSizer:add(Sizer, ButtSz, zxw:flags(base)), + _ = wxBoxSizer:add(Sizer, ButtSz, zxw:flags(wide)), ok = wxDialog:setSizer(Dialog, Sizer), ok = wxBoxSizer:layout(Sizer), - ok = wxFrame:center(Dialog), + ok = wxDialog:setSize(Dialog, {500, 130}), + ok = wxDialog:center(Dialog), ok = wxStyledTextCtrl:setFocus(NameTx), ok = case wxDialog:showModal(Dialog) of @@ -643,24 +649,26 @@ drop_key(Selected, State = #s{frame = Frame, j = J, accounts = Accounts, prefs = copy(State = #s{id = {_, #w{wx = ID_T}}}) -> String = wxStaticText:getLabel(ID_T), - CB = wxClipboard:get(), - ok = - case wxClipboard:open(CB) of - true -> - Text = wxTextDataObject:new([{text, String}]), - case wxClipboard:setData(CB, Text) of - true -> - R = wxClipboard:flush(CB), - log(info, "Address copied to system clipboard. Flushed: ~p", [R]); - false -> - log(info, "Failed to copy to clipboard") - end, - ok = wxClipboard:close(CB); - false -> - log(info, "Failed to acquire the clipboard.") - end, + ok = copy_to_clipboard(String), State. +copy_to_clipboard(String) -> + CB = wxClipboard:get(), + case wxClipboard:open(CB) of + true -> + Text = wxTextDataObject:new([{text, String}]), + case wxClipboard:setData(CB, Text) of + true -> + R = wxClipboard:flush(CB), + log(info, "String copied to system clipboard. Flushed: ~p", [R]); + false -> + log(info, "Failed to copy to clipboard") + end, + ok = wxClipboard:close(CB); + false -> + log(info, "Failed to acquire the clipboard.") + end. + www(State = #s{id = {_, #w{wx = ID_T}}}) -> String = wxStaticText:getLabel(ID_T), @@ -812,12 +820,15 @@ grids_dialogue(State = #s{frame = Frame, j = J}) -> _ = wxStaticBoxSizer:add(URL_Sz, URL_Tx, zxw:flags(wide)), ButtSz = wxBoxSizer:new(?wxHORIZONTAL), Affirm = wxButton:new(Dialog, ?wxID_OK), + Cancel = wxButton:new(Dialog, ?wxID_CANCEL), _ = wxBoxSizer:add(ButtSz, Affirm, zxw:flags(wide)), + _ = wxBoxSizer:add(ButtSz, Cancel, zxw:flags(wide)), _ = wxBoxSizer:add(Sizer, URL_Sz, zxw:flags(base)), - _ = wxBoxSizer:add(Sizer, ButtSz, zxw:flags(base)), + _ = wxBoxSizer:add(Sizer, ButtSz, zxw:flags(wide)), ok = wxDialog:setSizer(Dialog, Sizer), ok = wxBoxSizer:layout(Sizer), - ok = wxFrame:center(Dialog), + ok = wxDialog:setSize(Dialog, {500, 130}), + ok = wxDialog:center(Dialog), ok = wxStyledTextCtrl:setFocus(URL_Tx), ok = case wxDialog:showModal(Dialog) of @@ -852,21 +863,24 @@ do_selection(_, State) -> do_selection(0, State). -do_show(Accounts, State = #s{prefs = Prefs, picker = Picker}) -> +do_show(Accounts, State = #s{sizer = Sizer, prefs = Prefs, picker = Picker}) -> AKs = [Name || #poa{name = Name} <- Accounts], ok = wxListBox:set(Picker, AKs), - case Accounts of - [] -> - State; - [_] -> - Selected = 0, - ok = wxListBox:setSelection(Picker, Selected), - do_selection(Selected, State#s{accounts = Accounts}); - _ -> - Selected = maps:get(selected, Prefs, 0), - ok = wxListBox:setSelection(Picker, Selected), - do_selection(Selected, State#s{accounts = Accounts}) - end. + NewState = + case Accounts of + [] -> + State; + [_] -> + Selected = 0, + ok = wxListBox:setSelection(Picker, Selected), + do_selection(Selected, State#s{accounts = Accounts}); + _ -> + Selected = maps:get(selected, Prefs, 0), + ok = wxListBox:setSelection(Picker, Selected), + do_selection(Selected, State#s{accounts = Accounts}) + end, + ok = wxSizer:layout(Sizer), + NewState. do_wallet(none, #s{buttons = Buttons}) -> @@ -1006,32 +1020,44 @@ do_grids_mess_sig2(Request = #{"grids" := 1, #s{frame = Frame, j = J}) -> Dialog = wxDialog:new(Frame, ?wxID_ANY, J("Message Signature Request")), Sizer = wxBoxSizer:new(?wxVERTICAL), - Instruction = - J("The server at the URL below is requesting you sign the following message."), - InstTx = wxStaticText:new(Dialog, ?wxID_ANY, Instruction), - AcctSz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, J("Signature Account")}]), - AcctTx = wxStaticText:new(Dialog, ?wxID_ANY, ID), - _ = wxStaticBoxSizer:add(AcctSz, AcctTx, zxw:flags(wide)), - URL_Label = J("Originating URL"), - URL_Sz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, URL_Label}]), - URL_Tx = wxStaticText:new(Dialog, ?wxID_ANY, URL), - _ = wxStaticBoxSizer:add(URL_Sz, URL_Tx, zxw:flags(wide)), - MessSz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, J("CallData")}]), - MessStyle = ?wxTE_MULTILINE bor ?wxTE_READONLY, - MessTx = wxTextCtrl:new(Dialog, ?wxID_ANY, [{value, CallData}, {style, MessStyle}]), - _ = wxStaticBoxSizer:add(MessSz, MessTx, zxw:flags(wide)), + + Title = J("Transaction Signature Request"), + TitleTx = wxStaticText:new(Dialog, ?wxID_ANY, Title), + Big = wxFont:new(20, ?wxMODERN, ?wxNORMAL, ?wxNORMAL, [{face, "Sans"}]), + true = wxStaticText:setFont(TitleTx, Big), + + LabeledSz = wxStaticBoxSizer:new(?wxVERTICAL, Dialog, [{label, J("Details")}]), + DetailSz = wxFlexGridSizer:new(4, 2, 5, 5), + Details = + [J("Account"), ID, + J("Chain"), Chain, + J("Network ID"), NetID, + J("Originating URL"), URL], + AddDetail = + fun(D) -> + T = wxStaticText:new(Dialog, ?wxID_ANY, D), + _ = wxFlexGridSizer:add(DetailSz, T) + end, + ok = lists:foreach(AddDetail, Details), + _ = wxStaticBoxSizer:add(LabeledSz, DetailSz, zxw:flags(wide)), + + DataLabel = wxStaticText:new(Dialog, ?wxID_ANY, J("TX Data")), + DataStyle = ?wxTE_MULTILINE bor ?wxTE_READONLY, + DataTx = wxTextCtrl:new(Dialog, ?wxID_ANY, [{value, CallData}, {style, DataStyle}]), + ButtSz = wxBoxSizer:new(?wxHORIZONTAL), Affirm = wxButton:new(Dialog, ?wxID_OK), Cancel = wxButton:new(Dialog, ?wxID_CANCEL), _ = wxBoxSizer:add(ButtSz, Affirm, zxw:flags(wide)), _ = wxBoxSizer:add(ButtSz, Cancel, zxw:flags(wide)), - _ = wxBoxSizer:add(Sizer, InstTx, zxw:flags(wide)), - _ = wxBoxSizer:add(Sizer, AcctSz, zxw:flags(wide)), - _ = wxBoxSizer:add(Sizer, URL_Sz, zxw:flags(wide)), - _ = wxBoxSizer:add(Sizer, MessSz, zxw:flags(wide)), + + _ = wxBoxSizer:add(Sizer, TitleTx, zxw:flags(base)), + _ = wxBoxSizer:add(Sizer, LabeledSz, zxw:flags(base)), + _ = wxBoxSizer:add(Sizer, DataLabel, zxw:flags(base)), + _ = wxBoxSizer:add(Sizer, DataTx, zxw:flags(wide)), _ = wxBoxSizer:add(Sizer, ButtSz, zxw:flags(base)), ok = wxDialog:setSizer(Dialog, Sizer), - ok = wxDialog:setSize(Dialog, {500, 500}), + ok = wxDialog:setSize(Dialog, {700, 400}), ok = wxBoxSizer:layout(Sizer), ok = wxFrame:center(Dialog), ok = diff --git a/src/gmc_jt.erl b/src/gmc_jt.erl index 0e838b6..3e34904 100644 --- a/src/gmc_jt.erl +++ b/src/gmc_jt.erl @@ -15,6 +15,7 @@ %%% translation library is retained). -module(gmc_jt). +-vsn("0.1.1"). -export([read_translations/1, j/2, oneshot_j/2]). diff --git a/src/gmc_key_master.erl b/src/gmc_key_master.erl index d54a4a3..fc1eac7 100644 --- a/src/gmc_key_master.erl +++ b/src/gmc_key_master.erl @@ -8,6 +8,7 @@ %%% @end -module(gmc_key_master). +-vsn("0.1.1"). -export([make_key/2, encode/1, decode/1]). diff --git a/src/gmc_sup.erl b/src/gmc_sup.erl index ef76094..d7039bf 100644 --- a/src/gmc_sup.erl +++ b/src/gmc_sup.erl @@ -12,7 +12,7 @@ %%% @end -module(gmc_sup). --vsn("0.1.0"). +-vsn("0.1.1"). -behaviour(supervisor). -author("Craig Everett "). -copyright("QPQ AG "). diff --git a/src/gmc_v.erl b/src/gmc_v.erl index f8e3309..8a2b4e0 100644 --- a/src/gmc_v.erl +++ b/src/gmc_v.erl @@ -1,5 +1,5 @@ -module(gmc_v). --vsn("0.1.0"). +-vsn("0.1.1"). -author("Craig Everett "). -copyright("QPQ AG "). -license("GPL-3.0-or-later"). diff --git a/src/gmc_v_netman.erl b/src/gmc_v_netman.erl index 3ac2085..50c7dcd 100644 --- a/src/gmc_v_netman.erl +++ b/src/gmc_v_netman.erl @@ -1,11 +1,11 @@ -module(gmc_v_netman). --vsn("0.1.0"). +-vsn("0.1.1"). -author("Craig Everett "). -copyright("QPQ AG "). -license("GPL-3.0-or-later"). -behavior(wx_object). --behavior(gmc_v). +%-behavior(gmc_v). -include_lib("wx/include/wx.hrl"). -export([to_front/1]). -export([set_manifest/1]). diff --git a/src/gmc_v_wallman.erl b/src/gmc_v_wallman.erl index fa608a2..479432c 100644 --- a/src/gmc_v_wallman.erl +++ b/src/gmc_v_wallman.erl @@ -1,11 +1,11 @@ -module(gmc_v_wallman). --vsn("0.1.0"). +-vsn("0.1.1"). -author("Craig Everett "). -copyright("QPQ AG "). -license("GPL-3.0-or-later"). -behavior(wx_object). --behavior(gmc_v). +%-behavior(gmc_v). -include_lib("wx/include/wx.hrl"). -export([to_front/1]). -export([show/2]). diff --git a/zomp.meta b/zomp.meta index 031ac42..91b0ef5 100644 --- a/zomp.meta +++ b/zomp.meta @@ -2,14 +2,14 @@ {type,gui}. {modules,[]}. {prefix,"gmc"}. -{desc,"A desktop client for the Gajumaru network of blockchain networks"}. {author,"Craig Everett"}. -{package_id,{"otpr","clutch",{0,1,0}}}. -{deps,[{"otpr","aeserialization",{0,1,2}}, +{desc,"A desktop client for the Gajumaru network of blockchain networks"}. +{package_id,{"otpr","clutch",{0,1,1}}}. +{deps,[{"otpr","hakuzaru",{0,2,0}}, + {"otpr","aesophia",{8,0,1}}, + {"otpr","aeserialization",{0,1,2}}, {"otpr","zj",{1,1,0}}, - {"otpr","aesophia",{7,1,2}}, {"otpr","aebytecode",{3,2,1}}, - {"otpr","hakuzaru",{0,1,0}}, {"otpr","erl_base58",{0,1,0}}, {"otpr","eblake2",{1,0,0}}, {"otpr","ec_utils",{1,0,0}},