夢に出る実家、中学ごろに引っ越した今の実家ではなくて、いっこ前の家なことがほとんどなのが不思議。三つ子の魂なのか……?
日記
今日はなぜかかなり滅入っていて、ひとまず歩くかと思って外に出たけど、目当ての店は閉まっており、そうか〜とか言いながら川まで来たりしている。下りたらところどころ花火の煙が上がっていて、地面から蛙と虫の声がして、水が背景になっていた。
目に映る景色のうち、かなりのものが残せるようになった。言葉は元より、写真も技術の進歩が進み、きめ細かで鮮やかな場面を切り取る。切り取ってからさらに手を入れている、という非難もあるけど、少なくとも自分がそのときを思い出すための道具としてならどうあってもいいと勝手に思っている。
まだ難しいなと感じるのは連続したシーンで、録画などをしてもあまりしっくりこないことが多い。どちらかといえば、その残した録画を見たときに、当時のハッとした心持ちを思い出せない。これは、技術的に写真ほど細やかに残らないからなのか、残してみるとなんだそんなものかとなってしまうからなのかわからない。後者は写真にも少し感じるものだけど、動画で顕著だと感じる。
ところで、普段おもしろいと感じるときのひとつに、わからない部分がある光景を、自分の頭の引き出しをどんどん開けて理解しようとするとき、があるのではないかと思っている。落語を見て実際のシーンを勝手に思い浮かべるのが典型的だけど、映画でも速さや重さなどをイメージして確かに疲れそうと考えたりする。
似た話題で、録画に対して考える余地を見出だせず、つまり記憶を呼び起こせないので、当時の気持ちとずれるのかも、と考えることはできそう。写真は時間の軸の分の余地があるので、より思い出す余地が残されているということになる。
情報量が減ればよいというものではなくて、それぞれの量によって生まれる余地が変わりそう。言葉だけなら色も想像することになるし、録画でも気温やその前後なども思い浮かべられるはずではある。個人的に今そのバランスが合うのが言葉〜落語〜写真くらいなのかな、と思った。
結局今日は渡ったことのない橋を渡れたので収穫があった。そのうちパックマンみたいに歩き尽くしてしまうだろうけど、幸いこちらは忘れることができるし、意外と道の様子ががらりと変わることもあるはず。ここに楽しむ余地がある。
>はてなインターネット文学賞「記憶に残っている、あの日」
Chrome拡張機能をManifestV3に上げる活動
規模の小さい chrome-usercss-hogashi - Chrome ウェブストア から始めてみている。
Manifest V3 migration checklist - Chrome Developers を見ると結構色々ある。いっこずつ対応していったらよいのだけど、難関だったのは background pages の Service Worker 化。
色々 Google で検索しまくった結果、 localStorage を使っていたので Service Worker として invalid だったっぽい。のだけどエラーメッセージに何も現れてこなくてめちゃくちゃむずかった。
めっちゃむずい pic.twitter.com/Nxxj6RoC2b
— ラクヴェレ (@hogextend) 2021年7月31日
Service Worker で使える localStorage の代替を調べると、 chrome.storage というのがある。これは Chrome 拡張機能の機能として存在していて、 permission に storage とか足すと使える。
データとしては key/value なのだけど、呼び出しが非同期になっている(あと callback 形式)ので、単純に置き換えはできなくて、ちまちま Promise に包んで使うように変えたりした。
これでいいかと思ったらもう一回ハマって、 background pages からの sendMessage への応答 (sendResponse) が非同期だとおかしくなることがわかった。具体的には Unchecked runtime.lastError: The message port closed before a response was received
みたいなエラーが出ていて、 sendResponse で返したはずの値が返っていない。
この stackoverflow の回答はめちゃくちゃおもてなし度があって、 Chrome 拡張機能を使っている側としてはそのエラーを出してる拡張機能を消したら解決するけど、開発側としてはそのエラー自体への対処を知りたいよね、そういう目的で見に来た人に向けて書くね、みたいな内容で助かった。
それっぽいコードを書くと、 Promise が返る関数を呼んだとして、その then で sendResponse するような書き方にしたときにこうなる。
chrome.runtime.onMessage.addListener(() => { myAsyncFunction().then(result => { sendResponse(result); }); });
MDN を見ると、非同期に返す方法は 2通りあると書かれている。
To send an asynchronous response, there are two options:
https://developer.mozilla.org/en-US/docs/Mozilla/Add-ons/WebExtensions/API/runtime/onMessage
- return
true
from the event listener. This keeps thesendResponse()
function valid after the listener returns, so you can call it later. See an example.- return a
Promise
from the event listener, and resolve when you have the response (or reject it in case of an error). See an example.
イベントリスナから Promise を返すほうでやってみたけど、全然うまくいかなかった (なんかミスっているかもしれない……)。ここで Chrome 拡張機能の API ドキュメントを見に行くと、非同期ならイベントリスナからは true を返してくれと書かれていた。実際 true を返すほうでやって解決した。 Chrome 拡張機能のほうは Promise を返すほうに対応してないのかも?
This function becomes invalid when the event listener returns, unless you return true from the event listener to indicate you wish to send a response asynchronously (this will keep the message channel open to the other end until
https://developer.chrome.com/docs/extensions/reference/runtime/#event-onMessagesendResponse
is called).
のでこういう感じでできた。
chrome.runtime.onMessage.addListener(() => {
myAsyncFunction().then(result => {
sendResponse(result);
});
+ return true;
});
chrome.storage に切り替えるけど、 localStorage のほうで育ててきた UserCSS が消えるともの悲しいので、ちゃんと localStorage からのデータ移行もやることにしている。 onInstalled で自動で移行するので基本的には意識しなくていいようにしたけど、何かの拍子におかしくなったとき用に、 localStorage からのエクスポートも別に用意した。ということは、移行中は (localStorage 使うので) Manifest V3 にはできないので、もうしばらく V2 のままでいる必要がある。
これでみなさまがデータ移行できたら Manifest V3 に上げてよい、となるのだけど、できたよ〜みたいなデータを送信したりしないことにしているので、どのくらい待つのがいいのかむずい (普通に使っていたら数ヶ月くらいで十分な気もする)。
あえて順序を逆にするとどうか
Twitter でバズっているツイートにはリンクがないことが多い、という感覚は、逆にリンクがあるときはリンクを開いて満足してしまうということかもね、という会話をした。気をひく文や画像でも、リンクがあったら開いてしまい、ある程度納得してしまうのではないか、リンクがないときはなんだこれと思ったまま (他の人にも聞いて回るような具合で) RT するのではないか、みたいな仮説が立った。
リンクがないことで、より RT に結びつく、というのは、今まで感じていた因果と順序が逆で面白かった。因果が逆そうだな〜みたいなときでも意外と逆のままにして (あるいはあえて逆にして) 考えるとわかる事柄もありそう。
いまの天気でブログの背景を変える
ブログの背景を京都のいまの天気によって切り替えてみたくなって OpenWeather という天気 API を使って素朴に background-image を切り替えるようにした。アカウント作ったら API が使えて便利、ちょろっと js 書いて完成した。いま京都は曇りです。
写真は過去に取ってたやつを使っている、冬が好きなので夏だけど問答無用で雪の様子が出ます。
/* 京都の天気で背景変える */ const url = 'https://api.openweathermap.org/data/2.5/weather?lat=35&lon=135.7&units=Metric&appid=xxx'; fetch(url).then(res => res.json()).then(json => { const weather = json.weather; if (!weather || !weather[0]) { return; } const mainWeather = weather[0].main; const backgroundImageSrcs = { Clear: 'https://cdn-ak.f.st-hatena.com/images/fotolife/h/hogashi/20210715/20210715000656_original.jpg', Clouds: 'https://cdn-ak.f.st-hatena.com/images/fotolife/h/hogashi/20210714/20210714235934_original.jpg', Rain: 'https://cdn-ak.f.st-hatena.com/images/fotolife/h/hogashi/20210714/20210714233101_original.jpg', Snow: 'https://cdn-ak.f.st-hatena.com/images/fotolife/h/hogashi/20210714/20210714233101_original.jpg', }; const imageSrc = backgroundImageSrcs[mainWeather]; document.querySelector('html').style.backgroundImage = `url('${imageSrc}')`; });
html { background: top / contain repeat-y url(''); } body { /* 写真そのままだと見づらいこともあるのでちょっと白くする */ background-color: rgba(255, 255, 255, 0.4); }
天気の API 探したらこの記事を見つけたので見つつやってて、確かにアカウントつくった直後は API 使えなかったけどちょっと待ったら使えるようになるみたいな感じだった。