flow-flow-flow

[React] React x TypeScript でアップロードした画像ファイルをサムネイルとして表示する

f:id:thegriftsense:20210811003433j:plain 今やっている案件で、ユーザのアイコンの画像ファイルをアップロードして、その画像をサムネイルとして表示させて、OKボタン押下でサーバにアップロードするという処理があった。実装自体はシンプルだったけれど、はじめてやったのでメモしておく。

処理手順

  1. 1.inputタグ作成
  2. 2.inputタグのonChangeのハンドラ実装
  3. 3.ハンドラでのフローは、画像ファイルの取得、画像ファイルのbase64変換、state更新
  4. 4.imgタグ作成
  5. 5.stateをimgタグのsrcに設定

初めてだったのは、アップロードしたファイルをbase64に変換する処理くらい。 またひとつ賢くなってしまった。

コード全体

import React, { useCallback, useState } from "react";

export default function App() {
  // アップロードした画像ファイルから取得したbase64
  const [displayImage, setDisplayImage] = useState<string | ArrayBuffer | null>(null);
  /**
   * ファイルアップロードインプット変更時ハンドラ
   */
  const handlerChangeImageFileInput = useCallback((e: React.ChangeEvent<HTMLInputElement>) => {
    const file = e.target?.files?.[0];
    if (!file) {
      return;
    }
    // 選択されたファイルが画像ファイル以外だったらreturn
    if (file.type !== 'image/jpeg' && file.type !== 'image/png') {
      // バリデーションメッセージ表示
      console.log('jpeg/pngファイルを選択してください');
      return;
    }
    const reader = new FileReader();
    // base64に変換
    reader.readAsDataURL(file);
    reader.onload = () => {
      // base64に変換した結果をstateにセットする
      setDisplayImage(reader.result);
    };
  }, []);
  return (
    <div>
      <h1>
        React x TypeScript
        でアップロードした画像ファイルをサムネイルとして表示する
      </h1>
      <input type="file" onChange={handlerChangeImageFileInput} />
      <img
        src={(displayImage as string) || ""}
        alt=""
        width="100px"
        height="100px"
      />
    </div>
  );
}

codeSandBoxで書いたサンプルコードと動くやつ

codesandbox.io

おわり。

[TypeScript]TypeScriptプロジェクト始めようとしたらコンパイルで`Try changing the 'lib' compiler option to 'es2015' or later.`が出た

f:id:thegriftsense:20210808145535j:plain paizaでスキルチェックをしようと思ったけれど、言語選択でTypeScriptがなかった。 なので最小のTypeScriptプロジェクトを作成して、コンパイルしたJavaScriptのコードをコピペすればいいやと思ったので、作成手順をメモ。 またコンパイル時にTry changing the 'lib' compiler option to 'es2015' or later.というエラーがでたのでそのエラーの対応策もメモ。

package.json作成

$ npm init

typescript tsc を install

 $ npm i -D typescript tsc

tsconfig.json作成

$ ./node_modules/.bin/tsc --init

package.jsonにscript追加

コンパイルするときにTry changing the 'lib' compiler option to 'es2015' or later.が出ないように、--lib es6,domをつけてコンパイル時のライブラリを指定する。 -wwatchオプションで、付けておくとtsファイルの変更を監視してコンパイルしてくれる。

// src直下のtsファイルをes6を指定してコンパイル(監視)
"scripts":  {
  "tsc": "./node_modules/.bin/tsc ./src/**.ts -w --lib es6,dom"
}

src/index.tsを作成

コンパイルテスト

$ npm run tsc

[雑記] 碑文谷翔「おれ、仕事もお金もないけど、ゆり子のための時間、死ぬほどあるから」

仕事の仕事

今は electron で windows desktop app を作る案件をやっている。今日はアプリから、先方にもらったexeを起動する処理と、パスワード忘れのマジックリング周りの処理を実装した。先方からもらったアプリの実行ファイルをアプリから実行するだけだけれど、これがなかなかに面倒くさい。先方からもらったアプリの実行ファイルを実行するには、まずその実行ファイルのパスを取得しなければいけない。じゃあどうやって先方からもらったアプリの実行ファイルのパスを取得するのかといえば、レジストリパスから実行ファイルのパスを取得する別のexeファイルを実行して、そのexeの標準出力で吐き出された値を使う必要がある。この辺の実装は初めてでかなり手探りで実装した。そもそもレジストリというのは windows にしかないということを初めて知った。アプリ開発をすればするほど自分は Windows を嫌いになっていく。で、とりあえず先方からもらったアプリの起動テスト処理は無事実装できた。よかったよかった。

ぜんぜん知らないような処理の実装タスクも、フローを分割してひとつずつ進めていけばなんとかなるものだと最近おもう。それと、electron の技術的な記事を書いてくれてる人って割と決まっていて、electron のことで検索すると日本語の記事だとだいたい決まったブログに行き着く。とても助かっている。特にねこの足跡Rは、本当に何回助けられたことか。それとhttps://www.ncaq.net/ 。致命的な不具合で詰まったときに助けられた。自分は公式のドキュメントとか git hub の issue とかを、いちおう google 翻訳と deepL 翻訳を駆使して読んでみるけれど、まあ50%くらいは何言ってるのかわからない。ちゃんと公式ドキュメントを読める理解力と英語力を付けなければいけないとは思うけれども、まだその領域は無理。そもそも地頭が良くないから。

仕事はそんな感じ。

最近ドラマをよく観るな

昨日の深夜と今日の昼間、仕事している傍らで二本のドラマを観た。

アリバイ崩し承ります ☆☆

f:id:thegriftsense:20210727020552j:plain

タイトルの通りアリバイ崩しを主軸にした推理ドラマ。浜辺美波は可愛かった。 ただ自分にとってはどの話にもシリアスさが足りなかったし、人間ドラマという観点においても没入できるものがなかった。 自分が好きになれるキャラクタが不在のドラマは一話一話がとても長く感じるのである。

ヒモメン〜ヒモ更生プログラム〜 ☆☆☆

f:id:thegriftsense:20210727020633j:plain

昨日の深夜に観た。一話だけ観てみるつもりが、ぶっ通しで全話観てしまった。 主人公の設定が好みだった。一途で、働かない、自分に正直な青年(窪田正孝)。好きな人がいて、やりたくないことをしない生活。 とても自分の好みだった。『レンタルなんもしないひと』も好きだったし、自分はやりたくないことを徹底してやらない系の主人公が好きなのかもしれない。 「おれ、仕事もお金もないけど、ゆり子のための時間、死ぬほどあるから」 たしかにやりたくもない仕事やりながら、お金を稼いだとしても、好きな人のための時間がないならなんの意味もないよなあと考えさせられた。

あとこれはアニメだけれど、『ブラッククローバー』も観はじめた。まだep6だけれどまあまあ面白い。底抜けに明るい努力型の少年と、影のある天才型の少年の組み合わせは鉄板。

おわり。

[雑記] 日曜19時の諦めを 希望に見立てて今をやりすごす 仕事に行ける程強くなった サボれもしない程弱くなった

f:id:thegriftsense:20210725235333p:plain

YouTube で fire とかアーリリタイアの動画が流れてきてね

最近 YouTube でレコメンドされる動画に fire とかアーリーリタイア系の動画が出てきてばーっとディグってみているうちに、自分の幸福について考察しておいたほうがいいなと思った。自分の幸福について書き出して整理してみることにする。

やらなければいけないこと

  • 生活費を稼ぐ (手取り30万/月)

やりたくないこと

  • 仕事
  • 好きでもない人とのコミュニケーション

やりたいこと

  • 読書
  • アニメ、ドラマ、映画を観る
  • ゲーム
  • 睡眠
  • なにもしない一日
  • アプリ開発
  • 小説を書く
  • 引きこもり

できること

ざっくりこんなかんじになった。 自分のやらなければいけないことって、月に30万の手取りを稼ぐことだけなんだなという気づきがあった。とてもシンプルだ。 また、その月30万の手取りのためにやりたくない仕事やコミュニケーションが発生しているので、仕事以外で30万(手取り)の収入がありさえすれば、どうやら自分は幸福に暮らしていけるらしい。まとまった。

じゃあ次はどうやって仕事以外で、収入を得るかを考えなければいけない。 たとえばこのブログ、いまはまだ3記事目でアクセスも0だけれど、これから記事を重ねることで少しずつアクセスが伸びれば収入源になるかもしれない。 月に1万でも稼いでくれるようになれば、あと29万稼げばいいことになる。収入源の分散はリスクヘッジの基本だとどこかで見かけた気がする。ブログからの収入、開発したアプリからの収入、ほかできることが増えればそれを収入源にしていく。そうしてトータルの収入が30万/月(手取り)を超えた時、自分は仕事という地獄から開放される。

自分は目的がなければ動き出すことができないタイプの人間なので、目先の目標を立てておこうと思う。 とりあえず来週の目標を下記とする。

来週の目標

  • ブログ記事を3本は書く
  • 今作りかけのアプリをリリースする

ブログはいいと思う。文章として排泄することで思考が整理させる。 自分はインターネットが好きなので、こうやって自分の文章がインターネット上ののひとつの住所に所在を得ることにどこか幸福感を覚える。 これまではほぼROM専でインターネットを使ってきたけれど、これからはどんどんインターネットに自分の所在を残しておこうと思う。

おばけなんてないさ、おばけなんてうそさ、ねぼけたひとがみまちがえたのさ

f:id:thegriftsense:20210726000102j:plain 今日は『霊能力者 小田霧響子の嘘』というドラマを観た。事件を、人を幸福にする嘘で解決する霊能力者の話。「嘘」というのは自分もよく考えるテーマなので、考えさせられるところが多くあった。1話で小田霧響子(石原さとみ)が歌う『おばけなんてないさ』が可愛かったので、YouTubeで『おばけなんてないさ』を聴いて歌えるようになった。

扱う事件自体は軽めのものが多く、シリアス展開が好きな自分には少し物足りなかったけれど、原作だとここからシリアス展開になったりするのだろうか。それなら原作も読んでみたいと思った(現在は救済中らしいので、連載が再開されたら読んでみることにする)。原作の甲斐谷忍先生の作品は『ONE OUTS』と『LIAR GAME』がめちゃめちゃ好きである。 なんとなく甲斐谷先生の Wikipedia 見てきたけど、『ウイナーズサークルへようこそ』、『無敵の人』、『新・信長公記〜ノブナガくんと私〜』、この辺、ぜんぜん終えてないからちゃんと読んでおこう。 ほんとうに、時間とお金さえあればいちど好きになった作家の作品は自分が死ぬまでしっかり追っていきたい。

タイトル回収

最近4ma15さんの曲をよく聴く。自分の内面をえぐられるような歌詞が好きすぎる。 聴くようになったきっかけは、たしか spotify の誰かのプレイリストに入っていたのを偶然聴いたこと。『世迷言』という曲の「結局のところ音楽も 救えそうな奴から救ってく 綺麗なものを選んでは 照らすスポットライトみたいに」という歌詞が一日中、いや一週間、一ヶ月間、頭蓋の内側で繰り返されてはなれなくなった。いまでも、テレビで、ラジオで、インターネットで、色んな音楽を聴くたびに『世迷言』の歌詞が自動的に想起される。「結局のところ音楽も 救えそうな奴から救ってく」。たぶん一生頭から離れないフレーズだと思う。

世迷言/4ma15 feat.滲音かこい

悲しみに 苦しみに 昼も夜も費やして
昨日も今日も消えてった くずかごの中身だけ増えた
今更に湧き上がる 鈍らな詞も全部
飲み下し 眠らなきゃ 生きるため 働くために

弱いから 甘いから 囚われて絆されるんだ
一時間の値打ちだとか 八時間の鎖だとか
藻掻いても 足掻いても 何一つ変わらぬ日々を
絞っても 炙っても 虚ろな涙が滲むだけ

「『逆境は創造の糧だ』 いやそんなこと全部妄想だ
時間価値観全て切り売って この手に残ったものはあったか」
「結局のところ音楽も 救えそうな奴から救ってく
綺麗なものを選んでは 照らすスポットライトみたいに」

白けた日々の悲しみは、ただ滔々と流れてく/4ma15 feat.重音テト

日曜19時の諦めを
希望に見立てて今をやりすごす
仕事に行ける程強くなった
サボれもしない程弱くなった

おわり

[electron] electronアプリをURLから起動したい

いまやってる案件で、メール本文の「リンクからアプリを起動させたい」という要望がでたので対応するためにやり方を調べたのでメモ。 実装してみるまではできるか不安だったけれど、割と一瞬で実装できたのでよかった。

環境
- electron: 8.5.5
- electron-builder: 22.10.5

MacとWindowsで実装方法が異なるので順番に書いていく。

1. 実装方法 for Mac

Macは本当に一瞬で終わる。

"build": {
  ...
    "protocols": {
      "name": "myApp IM URL",
      "schemes": [
        "my-appname"
      ]
    },
   ...
 }

余談だけれど、上記は参考にした記事にあったサンプルコードで、こういうサンプルコードが出てきた時、自分は「schemeプロパティのmy-appnameのところにはアプリ名をいれればいいんだな。でもnameプロパティのmyApp IM URLのところには何を入れればいいんだよ。つーかnameプロパティの値が普通my-appnameじゃねえのかよ。あああ判りそうで判らん」みたいな、完成されたサンプルコードは目の前にあるのに、任意で値を指定しなといけない部分でつまづいてめちゃめちゃ歯がゆい経験をしたことが数え切れないくらいある。

ふつうにプログラミングできる人からは「ドキュメント読みなさいよ」と一蹴されてしまうような愚痴。

というわけでもう少し変わりやすく書くと、

"build": {
  ...
    "protocols": {
      "name": "myApp IM URL", // ここは自分のアプリ名を記述
      "schemes": [
        "my-appname" // ここにアプリを起動するときのプロトコルを記述。詳しくは後述する
      ]
    },
   ...
 }

という感じである。 nameプロパティの値は、たとえばアプリ名が「hoge」だったら name: "hoge" でOK。 schemesプロパティの値については、まずアプリを起動するときのリンクをどういうふうに作るかの説明が必要で、 サンプルコードのようにschemesプロパティが、schemes: ["my-appname"] だった場合、下記の様なリンクを踏むとアプリが起動する。

<a href="my-appname://">アプリ起動</a>

なのでschemes: ["piyo"] だった場合、href="piyo://"のリンクを踏めばアプリが起動することになる。 いろいろ記事を読んだけど、プロトコル部分はアプリの名前にするのが慣習のようなので、アプリ名がhogeなら、プロトコルもhogeとして、hoge://で起動するようにしておくのがいいと思われる。もちろんプロトコル部分のあとにはpathが指定できる。

Macの実装は以上。 試しにビルドして、下記の様なhtmlを作成してブラウザに表示させて、リンクをクリックしてみるとアプリが起動するはずである。

<a href="hoge://">アプリ起動</a>

こんな画面がでるはず。出れば勝ち。 f:id:thegriftsense:20210713005451p:plain

実装方法 for Windows

次windows。 package.jsonへの記述の他に、ファイルをひとつ作成しないといけないので手数がひとつ増える。 package.json部分はこのままコピペするだけで問題ない。

"build": {
    ...
    "nsis": {
      "include": "build/installer.nsh",
      "perMachine": true
    },
   ...
}

で、includeプロパティで指定している、build/installer.nshを作成してやらないといけない。 これもほぼコピペで、アプリの名前を記述する箇所だけ書き換えればOK。 publicディレクトリ配下のファイルがビルド後にbuild配下に反映されると思うので、ファイルを作成するときはpublicディレクトリ配下にinstaller.nshファイルを作成する。

!macro customHeader
    !system "echo '' > ${BUILD_RESOURCES_DIR}/customHeader"
!macroend

!macro preInit
    ; This macro is inserted at the beginning of the NSIS .OnInit callback
    !system "echo '' > ${BUILD_RESOURCES_DIR}/preInit"
!macroend

!macro customInit
    !system "echo '' > ${BUILD_RESOURCES_DIR}/customInit"
!macroend

!macro customInstall
    !system "echo '' > ${BUILD_RESOURCES_DIR}/customInstall"

    DetailPrint "Register My AppName URI Handler"
    DeleteRegKey HKCR "My AppName"
    WriteRegStr HKCR "My AppName" "" "URL:my-appname"
    WriteRegStr HKCR "My AppName" "URL Protocol" ""
    WriteRegStr HKCR "My AppName" "EveHQ NG SSO authentication Protocol" ""
    WriteRegStr HKCR "My AppName\DefaultIcon" "" "$INSTDIR\${APP_EXECUTABLE_FILENAME}"
    WriteRegStr HKCR "My AppName\shell" "" ""
    WriteRegStr HKCR "My AppName\shell\Open" "" ""
    WriteRegStr HKCR "My AppName\shell\Open\command" "" "$INSTDIR\${APP_EXECUTABLE_FILENAME} %1"
!macroend

!macro customInstallMode
    # set $isForceMachineInstall or $isForceCurrentInstall
    # to enforce one or the other modes.
!macroend

なんのこっちゃ判らんファイルだけど、とりあえず上記をコピペして、My AppName のところを自分のアプリの名称に変更すればOK。 これでwindows側の設定も終わりなので、ビルドして、Macのときのようにリンクを踏んでアプリが起動するかどうか確認する。 起動できれば勝ち。

詰まったところ

これはいっしゅん詰まったところだけど、はじめvscodeでmdファイルを作成してそのmdファイルに(hoge://)[アプリ起動]みたいなかんじでリンクを作成して、プレビューさせて、そのリンクを踏んでアプリ起動の確認をしていた。

うんともすんとも言わなかった。で、htmlファイルを作成してブラウザで読み込んでリンクを踏んだらちゃんとアプリが起動した。 自分以外にそんなことをする人がいるのかも謎だけれど、とりあえずvscodeでプレビューしたmdファイルからのリンクじゃアプリ起動しないよということが言いたかった。

あと、メールでリンクを送る際にhoge://みたいなプロトコルだとリンクが剥がされるみたいだったので、メールをhtml形式にして対応するか、メールにはhttps://のリンクを用意しておいて、開いた先のページでhoge://を踏ませるとか、ちょっと対応が必要そう。

自分の場合はメールをhtml形式にするで落ち着きそう。

おわり!

はてなブログの記事タイトルの横と下に線を入れる

はてなブログでブログ開設して、とりあえずタイトルくらいデザインを変えておくかと思ったのでこんな感じに変更した。

↓こんなかんじ(オレンジの線の部分)

f:id:thegriftsense:20210613020519p:plain

で、自分のように記事タイトルのデザインを変更したい人がいるかもしれないので、どうやってこの記事タイトル部分の線を実装したのかを書いておこうと思う。

1. 結論 (コピペで使えるコード)

下記のコードをコピペするだけで記事記事タイトルのデザインが変更される。 とりあえず下記のコードの ここから下をコピペ の部分をコピーしておいてほしい。

/* <system section="theme" selected="neutral"> */
@import "/css/theme/neutral/neutral.css";
/* </system> */

/* <system section="background" selected="default"> */
/* default */
/* </system> */

/* #FFF176 */
/* #FFAB00 */

/* ここから下をコピペ */
/* 記事title */
.entry-title {
  border-left: solid 10px #FFAB00;
  border-bottom: solid 3px #FFAB00;
  padding: 0 0 7px 15px !important;
}

ではどこにコピペすればいいのかの手順は下記の通り。

1. 管理画面からデザインを選択

f:id:thegriftsense:20210613024745p:plain

2. デザイン画面のスパナアイコンを押下

f:id:thegriftsense:20210613024812p:plain

3. デザインCSSを押下

f:id:thegriftsense:20210613024838p:plain

4. よくわからんコードの部分を押下

f:id:thegriftsense:20210613024904p:plain

5. こんなかんじのよくわからんコード書かれたエリアが表示される

f:id:thegriftsense:20210613024936p:plain

6. よくわからんコードの下の行に、上でコピーしていたコードを貼り付ける

こんな感じになる

f:id:thegriftsense:20210613025207p:plain

7. コードが表示されているエリアの外を押下するとエリアが閉じてデザインが反映される

8. 変更を保存するボタンを押下

f:id:thegriftsense:20210613025340p:plain

9.デザインが反映されているはずなので確認する。

おしまいです。

2. 蛇足 コピペしたコード(CSS)の説明

用語の説明は省きますので、わからない単語があった場合はググってみてください。 これから説明することが理解できれば、ほかのパーツについてもあるていど自由にスタイルを当てることができるようになるとおもいます。

.entry-title {  // -------- ①
  border-left: solid 10px #FFAB00;  // -------- ②
  border-bottom: solid 3px #FFAB00;  // -------- ③
  padding: 0 0 7px 15px !important;  // -------- ④
}

1. クラス名

.entry-title {  // -------- ①

記事タイトル部分のクラス名です。chromeのdevtoolからElementを見れば調べる事ができます。ここで指定したクラス名を持つ要素のスタイルを変更しますよというかんじです。

2. タイトル左のオレンジの border

  border-left: solid 10px #FFAB00;  // -------- ②

タイトル左のオレンジの border のスタイル指定です。 solid で border のスタイルの種類(一本線)、10px で border の太さ、 #FFAB00 で border の色を指定しています。

3. タイトル下のオレンジの border

border-bottom: solid 3px #FFAB00;  // -------- ③

②と一緒です

4. border と記事タイトルの隙間

padding: 0 0 7px 15px !important;  // -------- ④

paddingプロパティ で border と記事タイトルの隙間を設定してします。

0 0 7px 15px は順に上、右、下、左の間隔のサイズを指定しています。この指定の場合、下に7px、左に15px の間隔をあけるというスタイルになっています。

!important は paddingのスタイルが反映されなかったため、詳細度を上げるために着けております。自分も CSS 初心者のためこれであっているのかわかりませんがとりあえず反映されたのでOKです(力技💪)。

超ざっくりですが以上になります。

上の流れが理解できれば、つまりセレクタの指定、プロパティでのスタイルの指定ができるようになれば、はてなブログのデザインをほとんど自由に指定できるようになるとおもいます。