BearBoard #2 - coin search

BearBoard #2 - coin search

Search, add coins and persist changes

·

2 min read

Search with paginated results

CoinGecko api accepts any input whether provided with a currency name (bitcoin) or a symbol (btc). Response is not paginated - meaning, data coming back from API will include all search results (everything matching search input). I decided to implement sort of frontend pagination to control number of visible results - 5 is an optimal number.

Clicking arrows control the slice of response to be displayed.

search-coin.gif

Context menu

Well, names of the paragraphs below explain themselves, almost like the spaghetti code written to implement it. Quality of life features below.

All options are packed into a context menu to not pollute the main component.

Delete coin

With a little action confirmation.

delete-coin.gif

Here, how it looks in the code (stripped down to relevant lines) - SolidJS:

  • keep state of delete confirmation in signal
  • use <Show> to display delete / confirm button depending on the confirm state:

    • initially shouldConfirmDelete = false, so we display whatever is in the fallback (DeleteButton)
    • DeleteButton click sets shouldConfirmDelete to true , allowing Confirm delete to be displayed
    • When context menu loses mouse hover - swap back to initial delete button
export const CoinActionsMenu: Component = () => {

  const [shouldConfirmDelete, setShouldConfirmDelete] = createSignal(false);

  const DeleteButton = () => (
    <div
      data-tip='delete'
      onClick={() => setShouldConfirmDelete(true)}
    >
      <BsTrash size={MENU_ITEM_ICON_SIZE} />
    </div>
  );

  return (
      <div class='dropdown absolute right-2 top-2'>
        <label tabindex='0' class='btn btn-xs btn-circle btn-ghost'>
          <BiMenuAltRight size={MENU_ICON_SIZE} />
        </label>

        {/* Dropdown content */}
        <ul
          tabindex='0'
          class='dropdown-content menu p-3  shadow bg-base-100 rounded-box'
          onMouseLeave={() => setShouldConfirmDelete(false)}
        >
          {/* Delete btn */}
          <li>
            <Show when={shouldConfirmDelete()} fallback={DeleteButton}>
              {/* Confirm delete */}
              <div
                class=`bg-green-600`
                data-tip='Click to confirm'
                onClick={() => deleteCoinId(coinId)}
              >
                <BsCheck2 class='text-white' size={MENU_ITEM_ICON_SIZE} />
              </div>
            </Show>
          </li>
        </ul>
      </div>
    )
};

Reload coin

Currently the only way to get most up to data price data, needs to be repeated for each coin.

reload-coin.gif

Offline storage

Frontend of Tauri is displayed in a webView, meaning there is an access to many browser features like LocalStorage. Currently for storing just a simple array of coin ids it is sufficient to store it in this way without overengineering file/SQLite connection. I used localForage

persist.gif


Code for this step available on Github -> Link