bemusic/bemuse

View on GitHub
bemuse/src/devtools/playgrounds/custom-folder.tsx

Summary

Maintainability
C
7 hrs
Test Coverage
import React from 'react'
import _ from 'lodash'
import { sceneRoot } from 'bemuse/utils/main-element'
import { QueryClientProvider, useQuery } from 'react-query'
import {
  clearCustomFolder,
  getCustomFolderState,
  getDefaultCustomFolderContext,
  scanFolder,
  setCustomFolder,
} from 'bemuse/custom-folder'
import { queryClient } from 'bemuse/react-query'

const CustomFolderTester = () => {
  const context = getDefaultCustomFolderContext()
  const { isLoading, error, data } = useQuery('customFolder', async () => {
    const result = await getCustomFolderState(context)
    return result
  })
  const [status, setStatus] = React.useState('')

  if (isLoading) return <div>Loading...</div>

  if (error) return <div>An error has occurred: {`${error}`}</div>

  const setFolder = async () => {
    try {
      const handle = await window.showDirectoryPicker({ id: 'custom-folder' })
      await setCustomFolder(context, handle)
    } catch (e) {
      console.error(e)
      alert(`An error has occurred: ${e}`)
    } finally {
      queryClient.invalidateQueries('customFolder')
    }
  }

  const scan = async () => {
    try {
      await scanFolder(context, {
        log: console.log,
        setStatus: _.throttle((text) => setStatus(text), 100),
        updateState: (newState) => {
          queryClient.setQueryData('customFolder', newState)
        },
      })
    } catch (e) {
      console.error(e)
      alert(`An error has occurred: ${e}`)
    } finally {
      queryClient.invalidateQueries('customFolder')
    }
  }

  const clear = async () => {
    try {
      await clearCustomFolder(context)
    } catch (e) {
      console.error(e)
      alert(`An error has occurred: ${e}`)
    } finally {
      queryClient.invalidateQueries('customFolder')
    }
  }

  const songCount = ((data && data.songs) || []).length || 0
  const highlightIf = (condition: boolean) =>
    condition ? { color: '#ff8' } : {}
  return (
    <div>
      {data ? (
        <div>
          <p>✅ A folder has been selected</p>
          <hr />
          <p style={highlightIf(songCount === 0)}>
            Click the Scan button to scan for new songs 👉{' '}
            <button onClick={scan}>🕵️ Scan</button>
          </p>
          <p>
            <strong>Scan status:</strong>
            <br />
            <textarea
              value={status}
              readOnly
              style={{
                boxSizing: 'border-box',
                border: 'none',
                width: '100%',
                background: '#333',
                color: '#8e8',
                font: 'inherit',
              }}
              rows={3}
            />
          </p>
          <p>
            <strong>Number of songs in the database:</strong> {songCount}
          </p>
          <p style={highlightIf(songCount > 0)}>
            Once the songs are in the database, you can{' '}
            <a href='.' style={{ color: '#abc' }}>
              play them in Bemuse!
            </a>
          </p>
          <hr />
          <p>
            Click the Clear button to remove the folder selection 👉{' '}
            <button onClick={clear}>❌ Clear</button>
          </p>
        </div>
      ) : (
        <div>
          <p>No folder selected.</p>
          <p style={highlightIf(true)}>
            To get started 👉{' '}
            <button onClick={setFolder}>Set custom songs folder</button>
          </p>
          <p>
            The custom songs folder can contain any number of songs, but each
            song must be in a separate folder.
          </p>
        </div>
      )}
    </div>
  )
}

export function main() {
  sceneRoot.render(
    <QueryClientProvider client={queryClient}>
      <div style={{ margin: '0 auto', maxWidth: '32em', padding: '0 1em' }}>
        <h1>Bemuse custom songs folder console</h1>
        <p>
          This is a console for testing an upcoming feature: ✨
          <a
            style={{ color: '#abc' }}
            href='https://github.com/bemusic/bemuse/discussions/696'
            target='_blank'
            rel='noreferrer'
          >
            <strong>custom songs folder</strong>
          </a>
          ✨. You can set a folder to scan for custom songs, and it will be
          available in Bemuse game, no need to drag individual songs anymore! A
          more polished UI may be added in later, I hope.
        </p>
        <p>
          <a
            style={{ color: '#abc' }}
            href='https://github.com/bemusic/bemuse/discussions/696'
            target='_blank'
            rel='noreferrer'
          >
            Check out the announcement post for troubleshooting and known
            issues.
          </a>
        </p>
        <hr />
        <CustomFolderTester />
      </div>
    </QueryClientProvider>
  )
}