Frontend
This commit is contained in:
		@@ -2,12 +2,7 @@ from flask import Flask, render_template, request, jsonify
 | 
				
			|||||||
from .controller import Controller
 | 
					from .controller import Controller
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
app = Flask(
 | 
					app = Flask(__name__, static_folder="./client/build", static_url_path="/assets")
 | 
				
			||||||
    __name__,
 | 
					 | 
				
			||||||
    static_folder="./frontend/dist",
 | 
					 | 
				
			||||||
    static_url_path="/",
 | 
					 | 
				
			||||||
    template_folder="./frontend/dist",
 | 
					 | 
				
			||||||
)
 | 
					 | 
				
			||||||
controller = Controller()
 | 
					controller = Controller()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -46,13 +41,12 @@ def gain():
 | 
				
			|||||||
    return jsonify(controller.set_gain(amount))
 | 
					    return jsonify(controller.set_gain(amount))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@app.route("/")
 | 
					@app.route("/", defaults={"path": ""})
 | 
				
			||||||
@app.route("/<path:path>")
 | 
					@app.route("/<path:path>")
 | 
				
			||||||
def index(path: str = ""):
 | 
					def index(path: str):
 | 
				
			||||||
    print(f"PATH: {path}")
 | 
					    return render_template("index.html.j2")
 | 
				
			||||||
    return render_template("index.html")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@app.errorhandler(404)
 | 
					# @app.errorhandler(404)
 | 
				
			||||||
def not_found(*args, **kwargs):
 | 
					# def not_found(*args, **kwargs):
 | 
				
			||||||
    return render_template("index.html")
 | 
					#     return render_template("index.html.j2")
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										13
									
								
								fluidcontrol/client/package-lock.json
									
									
									
										generated
									
									
									
								
							
							
						
						
									
										13
									
								
								fluidcontrol/client/package-lock.json
									
									
									
										generated
									
									
									
								
							@@ -2234,6 +2234,11 @@
 | 
				
			|||||||
      "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==",
 | 
					      "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==",
 | 
				
			||||||
      "dev": true
 | 
					      "dev": true
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "regexparam": {
 | 
				
			||||||
 | 
					      "version": "1.3.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/regexparam/-/regexparam-1.3.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-6IQpFBv6e5vz1QAqI+V4k8P2e/3gRrqfCJ9FI+O1FLQTO+Uz6RXZEZOPmTJ6hlGj7gkERzY5BRCv09whKP96/g=="
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "regexpu-core": {
 | 
					    "regexpu-core": {
 | 
				
			||||||
      "version": "1.0.0",
 | 
					      "version": "1.0.0",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-1.0.0.tgz",
 | 
				
			||||||
@@ -2518,6 +2523,14 @@
 | 
				
			|||||||
      "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.16.7.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/svelte/-/svelte-3.16.7.tgz",
 | 
				
			||||||
      "integrity": "sha512-egrva1UklB1n7KAv179IhDpQzMGAvubJUlOQ9PitmmZmAfrCUEgrQnx2vPxn2s+mGV3aYegXvJ/yQ35N2SfnYQ=="
 | 
					      "integrity": "sha512-egrva1UklB1n7KAv179IhDpQzMGAvubJUlOQ9PitmmZmAfrCUEgrQnx2vPxn2s+mGV3aYegXvJ/yQ35N2SfnYQ=="
 | 
				
			||||||
    },
 | 
					    },
 | 
				
			||||||
 | 
					    "svelte-spa-router": {
 | 
				
			||||||
 | 
					      "version": "2.0.0",
 | 
				
			||||||
 | 
					      "resolved": "https://registry.npmjs.org/svelte-spa-router/-/svelte-spa-router-2.0.0.tgz",
 | 
				
			||||||
 | 
					      "integrity": "sha512-cIzRfHisJ87IzI9gyufkEXwaXT5hJrejMa3ryeClIzGLC2LzmKECfBhbitmYJ8gDfkto9tfZVXGvgQ9i7lmxXA==",
 | 
				
			||||||
 | 
					      "requires": {
 | 
				
			||||||
 | 
					        "regexparam": "^1.3.0"
 | 
				
			||||||
 | 
					      }
 | 
				
			||||||
 | 
					    },
 | 
				
			||||||
    "svgo": {
 | 
					    "svgo": {
 | 
				
			||||||
      "version": "1.3.2",
 | 
					      "version": "1.3.2",
 | 
				
			||||||
      "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz",
 | 
					      "resolved": "https://registry.npmjs.org/svgo/-/svgo-1.3.2.tgz",
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -15,8 +15,16 @@
 | 
				
			|||||||
    "> 0.5%",
 | 
					    "> 0.5%",
 | 
				
			||||||
    "last 2 versions",
 | 
					    "last 2 versions",
 | 
				
			||||||
    "Firefox ESR",
 | 
					    "Firefox ESR",
 | 
				
			||||||
    "not dead"
 | 
					    "not dead",
 | 
				
			||||||
 | 
					    "iOS > 9.3"
 | 
				
			||||||
  ],
 | 
					  ],
 | 
				
			||||||
 | 
					  "prettier": {
 | 
				
			||||||
 | 
					    "tabWidth": 2,
 | 
				
			||||||
 | 
					    "semi": false,
 | 
				
			||||||
 | 
					    "singleQuote": true,
 | 
				
			||||||
 | 
					    "bracketSpacing": false,
 | 
				
			||||||
 | 
					    "arrowParens": "always"
 | 
				
			||||||
 | 
					  },
 | 
				
			||||||
  "devDependencies": {
 | 
					  "devDependencies": {
 | 
				
			||||||
    "postcss": "^7.0.24",
 | 
					    "postcss": "^7.0.24",
 | 
				
			||||||
    "postcss-import": "^12.0.1",
 | 
					    "postcss-import": "^12.0.1",
 | 
				
			||||||
@@ -29,6 +37,7 @@
 | 
				
			|||||||
    "tailwindcss": "^1.1.4"
 | 
					    "tailwindcss": "^1.1.4"
 | 
				
			||||||
  },
 | 
					  },
 | 
				
			||||||
  "dependencies": {
 | 
					  "dependencies": {
 | 
				
			||||||
    "svelte": "^3.16.7"
 | 
					    "svelte": "^3.16.7",
 | 
				
			||||||
 | 
					    "svelte-spa-router": "^2.0.0"
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										13
									
								
								fluidcontrol/client/src/components/App.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										13
									
								
								fluidcontrol/client/src/components/App.svelte
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,13 @@
 | 
				
			|||||||
 | 
					<script>
 | 
				
			||||||
 | 
					  import Router from 'svelte-spa-router'
 | 
				
			||||||
 | 
					  import routes from '../routes'
 | 
				
			||||||
 | 
					  import Header from './Header.svelte'
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<div class="container py-4">
 | 
				
			||||||
 | 
					  <Header />
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <main>
 | 
				
			||||||
 | 
					    <Router {routes} />
 | 
				
			||||||
 | 
					  </main>
 | 
				
			||||||
 | 
					</div>
 | 
				
			||||||
							
								
								
									
										60
									
								
								fluidcontrol/client/src/components/Connect.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										60
									
								
								fluidcontrol/client/src/components/Connect.svelte
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,60 @@
 | 
				
			|||||||
 | 
					<script>
 | 
				
			||||||
 | 
					  import {fade} from 'svelte/transition'
 | 
				
			||||||
 | 
					  import {push} from 'svelte-spa-router'
 | 
				
			||||||
 | 
					  import controller from '../controller'
 | 
				
			||||||
 | 
					  import {connected} from '../stores'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const defaults = {
 | 
				
			||||||
 | 
					    host: '0.0.0.0',
 | 
				
			||||||
 | 
					    port: 9800
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let host = defaults.host
 | 
				
			||||||
 | 
					  let port = defaults.port
 | 
				
			||||||
 | 
					  let submitButton
 | 
				
			||||||
 | 
					  let error = ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function connect() {
 | 
				
			||||||
 | 
					    if (!host || !port) {
 | 
				
			||||||
 | 
					      error = 'You must supply a host and a port number to connect'
 | 
				
			||||||
 | 
					      return
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    error = ''
 | 
				
			||||||
 | 
					    const buttonValue = submitButton.value
 | 
				
			||||||
 | 
					    submitButton.value = 'Connecting...'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    controller
 | 
				
			||||||
 | 
					      .connect(host, port)
 | 
				
			||||||
 | 
					      .then((success) => {
 | 
				
			||||||
 | 
					        connected.set(success)
 | 
				
			||||||
 | 
					        push('/fonts')
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      .catch((err) => {
 | 
				
			||||||
 | 
					        error = 'Unable to connect. Try again or check the device.'
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      .finally(() => {
 | 
				
			||||||
 | 
					        submitButton.value = buttonValue
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{#if error}
 | 
				
			||||||
 | 
					  <p class="error" transition:fade>{error}</p>
 | 
				
			||||||
 | 
					{/if}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<form on:submit|preventDefault={connect}>
 | 
				
			||||||
 | 
					  <p>
 | 
				
			||||||
 | 
					    <label for="host">Host</label>
 | 
				
			||||||
 | 
					    <input type="text" name="host" id="host" bind:value={host} />
 | 
				
			||||||
 | 
					  </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <p>
 | 
				
			||||||
 | 
					    <label for="port">Port</label>
 | 
				
			||||||
 | 
					    <input type="number" name="port" id="port" min="0" bind:value={port} />
 | 
				
			||||||
 | 
					  </p>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <p class="actions">
 | 
				
			||||||
 | 
					    <button type="submit" bind:this={submitButton}>Connect</button>
 | 
				
			||||||
 | 
					  </p>
 | 
				
			||||||
 | 
					</form>
 | 
				
			||||||
							
								
								
									
										51
									
								
								fluidcontrol/client/src/components/Fonts.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								fluidcontrol/client/src/components/Fonts.svelte
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,51 @@
 | 
				
			|||||||
 | 
					<script>
 | 
				
			||||||
 | 
					  import {onMount} from 'svelte'
 | 
				
			||||||
 | 
					  import {fade} from 'svelte/transition'
 | 
				
			||||||
 | 
					  import {link} from 'svelte-spa-router'
 | 
				
			||||||
 | 
					  import controller from '../controller'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let fonts = []
 | 
				
			||||||
 | 
					  let loading = false
 | 
				
			||||||
 | 
					  let error = ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onMount(() => {
 | 
				
			||||||
 | 
					    refresh()
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function refresh() {
 | 
				
			||||||
 | 
					    error = ''
 | 
				
			||||||
 | 
					    loading = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    controller
 | 
				
			||||||
 | 
					      .getSoundfonts()
 | 
				
			||||||
 | 
					      .then((fetched) => {
 | 
				
			||||||
 | 
					        fonts = fetched
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      .catch((err) => {
 | 
				
			||||||
 | 
					        error = 'Could not fetch list of fonts'
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      .finally(() => (loading = false))
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{#if error}
 | 
				
			||||||
 | 
					  <p class="error" transition:fade>{error}</p>
 | 
				
			||||||
 | 
					{/if}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<ul class="mb-4">
 | 
				
			||||||
 | 
					  {#each fonts as font}
 | 
				
			||||||
 | 
					    <li>
 | 
				
			||||||
 | 
					      <a href="/fonts/{font.id}" use:link>{font.name}</a>
 | 
				
			||||||
 | 
					    </li>
 | 
				
			||||||
 | 
					  {:else}
 | 
				
			||||||
 | 
					    {#if loading}
 | 
				
			||||||
 | 
					      <p class="text-gray-500">Loading...</p>
 | 
				
			||||||
 | 
					    {:else if !error}
 | 
				
			||||||
 | 
					      <p class="text-red-500">No fonts!</p>
 | 
				
			||||||
 | 
					    {/if}
 | 
				
			||||||
 | 
					  {/each}
 | 
				
			||||||
 | 
					</ul>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{#if !loading}
 | 
				
			||||||
 | 
					  <button on:click|preventDefault={refresh}>Refresh</button>
 | 
				
			||||||
 | 
					{/if}
 | 
				
			||||||
							
								
								
									
										75
									
								
								fluidcontrol/client/src/components/Fonts/Font.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										75
									
								
								fluidcontrol/client/src/components/Fonts/Font.svelte
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,75 @@
 | 
				
			|||||||
 | 
					<script>
 | 
				
			||||||
 | 
					  import {onMount} from 'svelte'
 | 
				
			||||||
 | 
					  import {fade} from 'svelte/transition'
 | 
				
			||||||
 | 
					  import controller from '../../controller'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  export let params = {}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  let instruments = []
 | 
				
			||||||
 | 
					  let loading = false
 | 
				
			||||||
 | 
					  let error = ''
 | 
				
			||||||
 | 
					  let selected = undefined
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  onMount(() => {
 | 
				
			||||||
 | 
					    refresh()
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function refresh() {
 | 
				
			||||||
 | 
					    error = ''
 | 
				
			||||||
 | 
					    loading = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    controller
 | 
				
			||||||
 | 
					      .getInstruments(params.id)
 | 
				
			||||||
 | 
					      .then((fetched) => {
 | 
				
			||||||
 | 
					        instruments = fetched
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      .catch((err) => {
 | 
				
			||||||
 | 
					        error = 'Could not fetch list of instruments'
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      .finally(() => (loading = false))
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  function select(instrument) {
 | 
				
			||||||
 | 
					    error = ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    controller
 | 
				
			||||||
 | 
					      .select({
 | 
				
			||||||
 | 
					        channel: 0,
 | 
				
			||||||
 | 
					        instrument: params.id,
 | 
				
			||||||
 | 
					        bank: instrument.bank,
 | 
				
			||||||
 | 
					        program: instrument.program
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      .then(() => {
 | 
				
			||||||
 | 
					        selected = instrument
 | 
				
			||||||
 | 
					      })
 | 
				
			||||||
 | 
					      .catch((err) => (error = 'Could not select instrument'))
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{#if error}
 | 
				
			||||||
 | 
					  <p class="error" transition:fade>{error}</p>
 | 
				
			||||||
 | 
					{/if}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<ul class="mb-4">
 | 
				
			||||||
 | 
					  {#each instruments as instrument}
 | 
				
			||||||
 | 
					    <li
 | 
				
			||||||
 | 
					      class="bg-gray-200 dark:bg-gray-800 p-2 border-b border-gray-400
 | 
				
			||||||
 | 
					      dark:border-gray-600 cursor-pointer flex items-center"
 | 
				
			||||||
 | 
					      on:click|preventDefault={() => select(instrument)}>
 | 
				
			||||||
 | 
					      <span class="flex-auto">{instrument.name}</span>
 | 
				
			||||||
 | 
					      <span>
 | 
				
			||||||
 | 
					        {#if selected === instrument}✅{/if}
 | 
				
			||||||
 | 
					      </span>
 | 
				
			||||||
 | 
					    </li>
 | 
				
			||||||
 | 
					  {:else}
 | 
				
			||||||
 | 
					    {#if loading}
 | 
				
			||||||
 | 
					      <p class="text-gray-500">Loading...</p>
 | 
				
			||||||
 | 
					    {:else if !error}
 | 
				
			||||||
 | 
					      <p>No instruments!</p>
 | 
				
			||||||
 | 
					    {/if}
 | 
				
			||||||
 | 
					  {/each}
 | 
				
			||||||
 | 
					</ul>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					{#if !loading}
 | 
				
			||||||
 | 
					  <button on:click|preventDefault={refresh}>Refresh</button>
 | 
				
			||||||
 | 
					{/if}
 | 
				
			||||||
							
								
								
									
										22
									
								
								fluidcontrol/client/src/components/Header.svelte
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								fluidcontrol/client/src/components/Header.svelte
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,22 @@
 | 
				
			|||||||
 | 
					<script>
 | 
				
			||||||
 | 
					  import {link} from 'svelte-spa-router'
 | 
				
			||||||
 | 
					  import {connected} from '../stores'
 | 
				
			||||||
 | 
					</script>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					<header class="flex items-center mb-4">
 | 
				
			||||||
 | 
					  <nav class="flex-auto horizontal">
 | 
				
			||||||
 | 
					    <ul>
 | 
				
			||||||
 | 
					      {#if $connected}
 | 
				
			||||||
 | 
					        <li>
 | 
				
			||||||
 | 
					          <a href="/fonts" use:link>Fonts</a>
 | 
				
			||||||
 | 
					        </li>
 | 
				
			||||||
 | 
					      {:else}
 | 
				
			||||||
 | 
					        <li>
 | 
				
			||||||
 | 
					          <a href="/connect" use:link>Connect</a>
 | 
				
			||||||
 | 
					        </li>
 | 
				
			||||||
 | 
					      {/if}
 | 
				
			||||||
 | 
					    </ul>
 | 
				
			||||||
 | 
					  </nav>
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  <div class="flex-none">{$connected ? '✅' : '❌'}</div>
 | 
				
			||||||
 | 
					</header>
 | 
				
			||||||
							
								
								
									
										61
									
								
								fluidcontrol/client/src/controller.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										61
									
								
								fluidcontrol/client/src/controller.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,61 @@
 | 
				
			|||||||
 | 
					class Controller {
 | 
				
			||||||
 | 
					  constructor() {
 | 
				
			||||||
 | 
					    // TODO
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async connect(host = '0.0.0.0', port = 9800) {
 | 
				
			||||||
 | 
					    const url = this.apiURL('/api/connect', {
 | 
				
			||||||
 | 
					      host,
 | 
				
			||||||
 | 
					      port
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const response = await fetch(url)
 | 
				
			||||||
 | 
					    const data = await response.json()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return data.success
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async getSoundfonts() {
 | 
				
			||||||
 | 
					    const url = this.apiURL('/api/soundfonts')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const response = await fetch(url)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return response.json()
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async getInstruments(font) {
 | 
				
			||||||
 | 
					    const url = this.apiURL('/api/instruments', {
 | 
				
			||||||
 | 
					      font
 | 
				
			||||||
 | 
					    })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const response = await fetch(url)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return response.json()
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  async select({channel, instrument, bank, program}) {
 | 
				
			||||||
 | 
					    const url = this.apiURL('/api/select', {channel, instrument, bank, program})
 | 
				
			||||||
 | 
					    const response = await fetch(url)
 | 
				
			||||||
 | 
					    const data = response.json()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return data.success
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  // Private
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  apiURL(path, params = {}) {
 | 
				
			||||||
 | 
					    const url = new URL(document.location)
 | 
				
			||||||
 | 
					    url.pathname = path
 | 
				
			||||||
 | 
					    url.hash = ''
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    for (let [key, value] of Object.entries(params)) {
 | 
				
			||||||
 | 
					      url.searchParams.append(key, value)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    return url
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					const controller = new Controller()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default controller
 | 
				
			||||||
							
								
								
									
										73
									
								
								fluidcontrol/client/src/css/custom.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										73
									
								
								fluidcontrol/client/src/css/custom.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,73 @@
 | 
				
			|||||||
 | 
					form {
 | 
				
			||||||
 | 
					  & > p {
 | 
				
			||||||
 | 
					    @apply mb-4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @screen md {
 | 
				
			||||||
 | 
					      @apply flex items-center;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  & label {
 | 
				
			||||||
 | 
					    @apply font-semibold block w-full mb-2;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @screen md {
 | 
				
			||||||
 | 
					      @apply w-1/6 inline-block mr-4 mb-0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					  
 | 
				
			||||||
 | 
					  & input:not([type="submit"]), & textarea, & select {
 | 
				
			||||||
 | 
					    @apply w-full;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    @screen md {
 | 
				
			||||||
 | 
					      @apply flex-auto;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  & > .actions {
 | 
				
			||||||
 | 
					    @screen md {
 | 
				
			||||||
 | 
					      @apply w-5/6 ml-auto;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					input, textarea {
 | 
				
			||||||
 | 
					  @apply bg-white text-gray-900 px-3 py-2 rounded border border-gray-300;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  &:focus {
 | 
				
			||||||
 | 
					    @apply bg-gray-100;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @screen dark {
 | 
				
			||||||
 | 
					    @apply bg-black text-gray-100 border border-gray-600;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &:focus {
 | 
				
			||||||
 | 
					      @apply bg-gray-900;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					input[type="submit"], button, .button {
 | 
				
			||||||
 | 
					  @apply bg-gray-400 text-gray-900 px-4 py-2 rounded;
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					.error {
 | 
				
			||||||
 | 
					  @apply bg-red-100 text-red-900 p-2 mb-4 rounded;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  @screen dark {
 | 
				
			||||||
 | 
					    @apply bg-red-700 text-red-100;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					nav.horizontal {
 | 
				
			||||||
 | 
					  & li {
 | 
				
			||||||
 | 
					    @apply inline-block mr-4;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    &:last-child {
 | 
				
			||||||
 | 
					      @apply mr-0;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  & :any-link {
 | 
				
			||||||
 | 
					    @apply underline;
 | 
				
			||||||
 | 
					  }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										6
									
								
								fluidcontrol/client/src/css/main.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								fluidcontrol/client/src/css/main.css
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,6 @@
 | 
				
			|||||||
 | 
					@import "tailwindcss/base";
 | 
				
			||||||
 | 
					@import "tailwindcss/components";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@import "./custom.css";
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					@import "tailwindcss/utilities";
 | 
				
			||||||
@@ -0,0 +1,10 @@
 | 
				
			|||||||
 | 
					import './css/main.css'
 | 
				
			||||||
 | 
					import App from './components/App.svelte'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					document.addEventListener('DOMContentLoaded', () => {
 | 
				
			||||||
 | 
					  document.querySelector('#loading').remove()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					  const app = new App({
 | 
				
			||||||
 | 
					    target: document.querySelector('#app')
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 | 
					})
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										9
									
								
								fluidcontrol/client/src/routes.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										9
									
								
								fluidcontrol/client/src/routes.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,9 @@
 | 
				
			|||||||
 | 
					import Connect from './components/Connect.svelte'
 | 
				
			||||||
 | 
					import Fonts from './components/Fonts.svelte'
 | 
				
			||||||
 | 
					import Font from './components/Fonts/Font.svelte'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export default {
 | 
				
			||||||
 | 
					  '/connect': Connect,
 | 
				
			||||||
 | 
					  '/fonts': Fonts,
 | 
				
			||||||
 | 
					  '/fonts/:id': Font
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
							
								
								
									
										5
									
								
								fluidcontrol/client/src/stores.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										5
									
								
								fluidcontrol/client/src/stores.js
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,5 @@
 | 
				
			|||||||
 | 
					import {writable} from 'svelte/store'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					export const connected = writable(false)
 | 
				
			||||||
 | 
					export const fonts = writable([])
 | 
				
			||||||
 | 
					export const instruments = writable([])
 | 
				
			||||||
							
								
								
									
										17
									
								
								fluidcontrol/templates/index.html.j2
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								fluidcontrol/templates/index.html.j2
									
									
									
									
									
										Normal file
									
								
							@@ -0,0 +1,17 @@
 | 
				
			|||||||
 | 
					<!DOCTYPE html>
 | 
				
			||||||
 | 
					<html lang="en">
 | 
				
			||||||
 | 
					<head>
 | 
				
			||||||
 | 
					  <meta charset="UTF-8">
 | 
				
			||||||
 | 
					  <meta name="viewport" content="width=device-width, initial-scale=1.0">
 | 
				
			||||||
 | 
					  <meta http-equiv="X-UA-Compatible" content="ie=edge">
 | 
				
			||||||
 | 
					  <title>FluidControl</title>
 | 
				
			||||||
 | 
					  <link rel="stylesheet" href="{{ url_for("static", filename="main.css") }}">
 | 
				
			||||||
 | 
					  <script src="{{ url_for("static", filename="main.js") }}" type="text/javascript"></script>
 | 
				
			||||||
 | 
					</head>
 | 
				
			||||||
 | 
					<body class="bg-gray-100 dark:bg-gray-900 text-gray-900 dark:text-gray-100">
 | 
				
			||||||
 | 
					  <div id="app">
 | 
				
			||||||
 | 
					    <div id="loading" class="p-4">Loading…</div>
 | 
				
			||||||
 | 
					  </div>
 | 
				
			||||||
 | 
					  <noscript>You must have JavaScript enabled for FluidControl to work.</noscript>
 | 
				
			||||||
 | 
					</body>
 | 
				
			||||||
 | 
					</html>
 | 
				
			||||||
		Reference in New Issue
	
	Block a user