🤟

会社をサボるときに使えるアプリを作った

2022/12/26に公開

この記事はクソアプリ Advent Calendar 2022の20日目の記事です。

めちゃくちゃ遅刻しました..!すみません!

はじめに

いよいよ年末年始です。
皆さんはいつまで仕事でしょうか。
クリスマスを迎え、もうお休みモードなので、仕事に行きたくないですよね。
そういうわけで、簡単に仕事を休むための言い訳を考えることができるアプリを作りました。

https://twitter.com/yui_active/status/1607158580830142464?s=20&t=k8qKr1ciDpOhncPQuTD6Qg

絶対にサボってやるという強い意志を持った人が使えるアプリです。

使い方

使い方は「サボる理由を考える」ボタンを押すだけです。

Image from Gyazo

母が部屋を修理して消えてしまったなら仕方ないですね!仕事休みましょう!

技術スタック

  • Next.js
  • TypeScript
  • Chakra UI
  • Vercel

あとは諸々のnpmパッケージ等

UIに関して

今回、なんてことないクソアプリなのですが、文字をパタパタさせるところだけ微妙にこだわりました。
このパタパタする感じのUIどこかで見たことありませんか?

そう、今は懐かしい電車の反転フラップ式案内表示機です。

今年の最初にいよいよ電車のパタパタがなくなりました。
関連記事↓

https://www.watch.impress.co.jp/docs/news/1379966.html

そこで、今回せっかくならということで、このUIを採用することにしました。

そのために使ったライブラリは@pqina/flipです。
このライブラリを使うにあたって少しひと悶着あったので以下に書きます。

@pqina/flipに関して

yarn add @pqina/flip

を行ったあとはhttps://codesandbox.io/s/react-flip-demo-txoux に詳しい実装方法が乗っているので、クラス型→関数型に書き換えながら書いていきます。

src/components/Flip.tsx
import Tick from '@pqina/flip';
import '@pqina/flip/dist/flip.min.css';

ただ、このライブラリにはtypesの設定がなく、import部分でエラーとなるため、d.tsファイルを作成する必要があります。

types/pqina__flip.d.ts
declare module '@pqina/flip';

これでOK。
あとは続きを書いていきます。

src/components/Flip.tsx
type Props = {
  text: string;
};

const Flip: React.FC<Props> = ({ text }) => {
  const divRef = useRef(null);
  const tickRef = useRef(null);
  useEffect(() => {
    const didInit = (tick) => {
      tickRef.current = tick;
    };

    const currDiv = divRef.current;
    const tickValue = tickRef.current;
    Tick.DOM.create(currDiv, {
      text,
      didInit,
    });
    return () => Tick.DOM.destroy(tickValue);
  });

  useEffect(() => {
    if (tickRef.current) {
      tickRef.current.value = text;
    }
  }, [text]);

  return (
    <div ref={divRef} className="tick">
      <div data-repeat="true">
        <span data-view="flip"></span>
      </div>
    </div>
  );
};

export default Flip;

これで<Flip text='hoge'/>と書くだけでパタパタのUIが実現できるはずでした。
..が、このままでは以下のエラーが発生します。

Server Error
SyntaxError: Cannot use import statement outside a module

This error happened while generating the page. Any console logs will be displayed in the terminal window.

今回利用したモジュールはSSRに対応していなかったのでconst Flip = dynamic(() => import('../src/components/Flip'), { ssr: false });とすることで事なきを得ました。

そもそもどうやって前後の文字を入れ替えているかに関してはsetIntervalを組み合わせているだけなので省略します。
もし興味あれば以下の部分を見てください。

https://github.com/yuikoito/saboritai/blob/master/pages/index.tsx#L52-L74

※ちなみにリポジトリは以前途中まで作ってたやつを引き継いだので途中まで全く関係ないコミットがあります..このへんちゃんとやれという話ですね、ほんとうに(自戒)

作成時間

  • 仕組み部分→30分程度(まあ文字を入れ替えるだけなので..)
  • デザイン&UI実装→3時間ぐらい
  • Vercelのデプロイエラー→3時間ぐらい

謎にVercelのデプロイエラーで時間が湯水のように溶けました。
本当に世界一無駄な時間でした。

正確にはデプロイエラーにはならなかったのですが、動的OGPのためのパスが500エラーになるという問題が発生してなかなか解決できずにいました。
よくあるcanvasのバージョンを2.6.1に固定してnow-buildでごにょごにょしてみたいなやり方だと、nodeのバージョンが高すぎて無理だったので無理やりnode v14で動かしています。

node v18かつcanvas最新版でVercelデプロイの場合、動的OGP実現することができるんでしょうか・・?
調べた限り色んな人が苦戦してる感じでしたが、もし有識者の方いれば教えて下さい。

制作裏話

今回クソアプリを作ろうと思ってどんな理由で休むのが良いかChatGPTに相談してみたところ、普通に怒られました。

説教不要といっても怒ってきます。

言ってることはもっともなので、よいこの皆さんはサボらないようにしましょう。笑

あとがき

働きたくないという気分が全力に出たアプリが誕生してしまいました。
会社の人に怒られないことを祈ります。笑

Discussion