From 27da3581ae6f11da709b5427dc05cbbb32f55f7d Mon Sep 17 00:00:00 2001
From: Egor
Date: Mon, 29 May 2017 21:01:24 -0700
Subject: [PATCH] moving out mobile, random hue, ambience & blackout modes
---
mobile/.bowerrc | 4 -
mobile/.editorconfig | 20 -
mobile/.ember-cli | 10 -
mobile/.gitignore | 26 -
mobile/.jshintrc | 38 -
mobile/.travis.yml | 24 -
mobile/.watchmanconfig | 1 -
mobile/README.md | 44 -
mobile/app/app.js | 18 -
mobile/app/index.html | 30 -
mobile/app/pods/application/template.hbs | 1 -
.../components/bridge-finder/component.js | 167 -
.../components/bridge-finder/template.hbs | 81 -
.../pods/components/hue-controls/component.js | 265 -
.../pods/components/hue-controls/template.hbs | 49 -
.../pods/components/huegasm-app/component.js | 27 -
.../pods/components/huegasm-app/template.hbs | 5 -
.../pods/components/light-group/component.js | 213 -
.../pods/components/light-group/template.hbs | 11 -
.../lights-tab/color-picker/component.js | 58 -
.../lights-tab/color-picker/template.hbs | 1 -
.../pods/components/lights-tab/component.js | 278 -
.../pods/components/lights-tab/template.hbs | 42 -
.../add-soundcloud-sound-modal/component.js | 46 -
.../add-soundcloud-sound-modal/template.hbs | 15 -
.../pods/components/music-tab/component.js | 650 --
.../components/music-tab/mixins/helpers.js | 325 -
.../components/music-tab/mixins/visualizer.js | 94 -
.../pods/components/music-tab/template.hbs | 165 -
mobile/app/resolver.js | 3 -
mobile/app/router.js | 12 -
mobile/app/styles/app.scss | 49 -
mobile/app/styles/bootstrap.scss | 56 -
mobile/app/styles/bridge-finder.scss | 36 -
mobile/app/styles/common.scss | 11 -
mobile/app/styles/dimmer.scss | 80 -
mobile/app/styles/hue-controls.scss | 82 -
mobile/app/styles/huegasm-variables.scss | 8 -
mobile/app/styles/introjs.scss | 18 -
mobile/app/styles/light-group.scss | 66 -
mobile/app/styles/music-tab.scss | 360 -
mobile/app/styles/noui-slider.scss | 44 -
mobile/app/styles/paper.scss | 55 -
mobile/bower.json | 13 -
mobile/config/environment.js | 47 -
mobile/ember-cli-build.js | 26 -
mobile/ember-cordova/cordova/config.xml | 40 -
mobile/ember-cordova/cordova/hooks/README.md | 23 -
.../ember-cordova/cordova/platforms/.gitkeep | 0
mobile/ember-cordova/cordova/plugins/.gitkeep | 0
.../cordova/res/icon/android/hdpi.png | Bin 4030 -> 0 bytes
.../cordova/res/icon/android/ldpi.png | Bin 1896 -> 0 bytes
.../cordova/res/icon/android/mdpi.png | Bin 2507 -> 0 bytes
.../cordova/res/icon/android/xhdpi.png | Bin 5558 -> 0 bytes
.../cordova/res/icon/android/xxhdpi.png | Bin 8637 -> 0 bytes
.../cordova/res/icon/android/xxxhdpi.png | Bin 11566 -> 0 bytes
.../cordova/res/screen/android/land-hdpi.png | Bin 20041 -> 0 bytes
.../cordova/res/screen/android/land-ldpi.png | Bin 7568 -> 0 bytes
.../cordova/res/screen/android/land-mdpi.png | Bin 11562 -> 0 bytes
.../cordova/res/screen/android/land-xhdpi.png | Bin 33724 -> 0 bytes
.../res/screen/android/land-xxhdpi.png | Bin 45289 -> 0 bytes
.../res/screen/android/land-xxxhdpi.png | Bin 56645 -> 0 bytes
.../cordova/res/screen/android/port-hdpi.png | Bin 19809 -> 0 bytes
.../cordova/res/screen/android/port-ldpi.png | Bin 7507 -> 0 bytes
.../cordova/res/screen/android/port-mdpi.png | Bin 11516 -> 0 bytes
.../cordova/res/screen/android/port-xhdpi.png | Bin 33091 -> 0 bytes
.../res/screen/android/port-xxhdpi.png | Bin 44252 -> 0 bytes
.../res/screen/android/port-xxxhdpi.png | Bin 55416 -> 0 bytes
mobile/ember-cordova/cordova/www/.gitkeep | 0
mobile/ember-cordova/icon.svg | 599 --
mobile/ember-cordova/splash.svg | 228 -
mobile/package.json | 46 -
mobile/public/assets/images/colormap.png | Bin 6305 -> 0 bytes
mobile/public/assets/images/huegasm.png | Bin 3876 -> 0 bytes
.../assets/images/lights/filled/aura.svg | 19 -
.../filled/beyond_ceiling_pendant_table.svg | 7 -
.../assets/images/lights/filled/bloom.svg | 12 -
.../assets/images/lights/filled/br30.svg | 9 -
.../assets/images/lights/filled/br30_slim.svg | 15 -
.../assets/images/lights/filled/bridge_v1.svg | 18 -
.../assets/images/lights/filled/bridge_v2.svg | 19 -
.../images/lights/filled/ceiling_round.svg | 11 -
.../images/lights/filled/ceiling_square.svg | 13 -
.../assets/images/lights/filled/entity.svg | 11 -
.../assets/images/lights/filled/floor.svg | 10 -
.../public/assets/images/lights/filled/go.svg | 10 -
.../assets/images/lights/filled/gu10.svg | 19 -
.../images/lights/filled/gu10_perfectfit.svg | 19 -
.../assets/images/lights/filled/hds.svg | 8 -
.../assets/images/lights/filled/impulse.svg | 11 -
.../assets/images/lights/filled/iris.svg | 14 -
.../images/lights/filled/lightstrip.svg | 13 -
.../images/lights/filled/motion_sensor.svg | 15 -
.../images/lights/filled/pendant_oval.svg | 7 -
.../images/lights/filled/pendant_round.svg | 9 -
.../images/lights/filled/pendant_square.svg | 7 -
.../images/lights/filled/phoenix_ceiling.svg | 7 -
.../images/lights/filled/phoenix_down.svg | 8 -
.../assets/images/lights/filled/recessed.svg | 7 -
.../images/lights/filled/storylight.svg | 14 -
.../assets/images/lights/filled/table.svg | 10 -
.../assets/images/lights/filled/tap.svg | 10 -
.../lights/filled/white_and_color_e27.svg | 14 -
.../assets/images/lights/filled/white_e27.svg | 10 -
.../assets/images/lights/outline/aura.svg | 24 -
.../outline/beyond_ceiling_pendant_table.svg | 17 -
.../assets/images/lights/outline/bloom.svg | 17 -
.../assets/images/lights/outline/br30.svg | 27 -
.../images/lights/outline/br30_slim.svg | 60 -
.../images/lights/outline/bridge_v1.svg | 32 -
.../images/lights/outline/bridge_v2.svg | 32 -
.../images/lights/outline/ceiling_round.svg | 16 -
.../images/lights/outline/ceiling_square.svg | 18 -
.../assets/images/lights/outline/entity.svg | 1515 ----
.../assets/images/lights/outline/floor.svg | 15 -
.../assets/images/lights/outline/go.svg | 11 -
.../assets/images/lights/outline/gu10.svg | 93 -
.../images/lights/outline/gu10_perfectfit.svg | 36 -
.../assets/images/lights/outline/hds.svg | 14 -
.../assets/images/lights/outline/impulse.svg | 413 -
.../assets/images/lights/outline/iris.svg | 22 -
.../images/lights/outline/lightstrip.svg | 26 -
.../images/lights/outline/motion_sensor.svg | 9 -
.../assets/images/lights/outline/par16.svg | 28 -
.../images/lights/outline/pendant_oval.svg | 12 -
.../images/lights/outline/pendant_round.svg | 12 -
.../images/lights/outline/pendant_square.svg | 7 -
.../images/lights/outline/phoenix_ceiling.svg | 11 -
.../lights/outline/phoenix_ceiling_2.svg | 21 -
.../images/lights/outline/phoenix_down.svg | 7 -
.../images/lights/outline/phoenix_pendant.svg | 17 -
.../images/lights/outline/phoenix_table.svg | 15 -
.../images/lights/outline/phoenix_wall.svg | 14 -
.../assets/images/lights/outline/recessed.svg | 13 -
.../images/lights/outline/storylight.svg | 27 -
.../assets/images/lights/outline/table.svg | 15 -
.../assets/images/lights/outline/tap.svg | 9 -
.../lights/outline/white_and_color_e27.svg | 10 -
.../images/lights/outline/white_e27.svg | 15 -
.../public/assets/images/missingArtwork.png | Bin 1867 -> 0 bytes
mobile/public/assets/images/sc-white-sm.png | Bin 292 -> 0 bytes
mobile/public/assets/images/sc-white.png | Bin 3452 -> 0 bytes
mobile/public/assets/images/soundcloudUrl.png | Bin 56037 -> 0 bytes
mobile/vendor/cie-rgb-converter.js | 141 -
mobile/vendor/dancer.js | 709 --
mobile/yarn.lock | 7920 -----------------
.../pods/components/hue-controls/component.js | 10 +-
.../pods/components/hue-controls/template.hbs | 17 +-
.../pods/components/lights-tab/component.js | 18 +
.../pods/components/lights-tab/template.hbs | 12 +
.../pods/components/music-tab/component.js | 73 +-
.../components/music-tab/mixins/helpers.js | 53 +-
.../pods/components/music-tab/template.hbs | 44 +-
web/app/styles/common.scss | 4 +
web/app/styles/dimmer.scss | 5 +-
web/app/styles/hue-controls.scss | 47 +
web/app/styles/music-tab.scss | 7 +-
web/public/assets/images/promo.png | Bin 39472 -> 41248 bytes
web/yarn.lock | 123 +-
159 files changed, 267 insertions(+), 16512 deletions(-)
delete mode 100644 mobile/.bowerrc
delete mode 100644 mobile/.editorconfig
delete mode 100644 mobile/.ember-cli
delete mode 100644 mobile/.gitignore
delete mode 100644 mobile/.jshintrc
delete mode 100644 mobile/.travis.yml
delete mode 100644 mobile/.watchmanconfig
delete mode 100644 mobile/README.md
delete mode 100644 mobile/app/app.js
delete mode 100644 mobile/app/index.html
delete mode 100644 mobile/app/pods/application/template.hbs
delete mode 100644 mobile/app/pods/components/bridge-finder/component.js
delete mode 100644 mobile/app/pods/components/bridge-finder/template.hbs
delete mode 100644 mobile/app/pods/components/hue-controls/component.js
delete mode 100644 mobile/app/pods/components/hue-controls/template.hbs
delete mode 100644 mobile/app/pods/components/huegasm-app/component.js
delete mode 100644 mobile/app/pods/components/huegasm-app/template.hbs
delete mode 100644 mobile/app/pods/components/light-group/component.js
delete mode 100644 mobile/app/pods/components/light-group/template.hbs
delete mode 100644 mobile/app/pods/components/lights-tab/color-picker/component.js
delete mode 100644 mobile/app/pods/components/lights-tab/color-picker/template.hbs
delete mode 100644 mobile/app/pods/components/lights-tab/component.js
delete mode 100644 mobile/app/pods/components/lights-tab/template.hbs
delete mode 100644 mobile/app/pods/components/music-tab/add-soundcloud-sound-modal/component.js
delete mode 100644 mobile/app/pods/components/music-tab/add-soundcloud-sound-modal/template.hbs
delete mode 100644 mobile/app/pods/components/music-tab/component.js
delete mode 100644 mobile/app/pods/components/music-tab/mixins/helpers.js
delete mode 100644 mobile/app/pods/components/music-tab/mixins/visualizer.js
delete mode 100644 mobile/app/pods/components/music-tab/template.hbs
delete mode 100644 mobile/app/resolver.js
delete mode 100644 mobile/app/router.js
delete mode 100644 mobile/app/styles/app.scss
delete mode 100644 mobile/app/styles/bootstrap.scss
delete mode 100644 mobile/app/styles/bridge-finder.scss
delete mode 100644 mobile/app/styles/common.scss
delete mode 100644 mobile/app/styles/dimmer.scss
delete mode 100644 mobile/app/styles/hue-controls.scss
delete mode 100644 mobile/app/styles/huegasm-variables.scss
delete mode 100644 mobile/app/styles/introjs.scss
delete mode 100644 mobile/app/styles/light-group.scss
delete mode 100644 mobile/app/styles/music-tab.scss
delete mode 100644 mobile/app/styles/noui-slider.scss
delete mode 100644 mobile/app/styles/paper.scss
delete mode 100644 mobile/bower.json
delete mode 100644 mobile/config/environment.js
delete mode 100644 mobile/ember-cli-build.js
delete mode 100644 mobile/ember-cordova/cordova/config.xml
delete mode 100644 mobile/ember-cordova/cordova/hooks/README.md
delete mode 100644 mobile/ember-cordova/cordova/platforms/.gitkeep
delete mode 100644 mobile/ember-cordova/cordova/plugins/.gitkeep
delete mode 100644 mobile/ember-cordova/cordova/res/icon/android/hdpi.png
delete mode 100644 mobile/ember-cordova/cordova/res/icon/android/ldpi.png
delete mode 100644 mobile/ember-cordova/cordova/res/icon/android/mdpi.png
delete mode 100644 mobile/ember-cordova/cordova/res/icon/android/xhdpi.png
delete mode 100644 mobile/ember-cordova/cordova/res/icon/android/xxhdpi.png
delete mode 100644 mobile/ember-cordova/cordova/res/icon/android/xxxhdpi.png
delete mode 100644 mobile/ember-cordova/cordova/res/screen/android/land-hdpi.png
delete mode 100644 mobile/ember-cordova/cordova/res/screen/android/land-ldpi.png
delete mode 100644 mobile/ember-cordova/cordova/res/screen/android/land-mdpi.png
delete mode 100644 mobile/ember-cordova/cordova/res/screen/android/land-xhdpi.png
delete mode 100644 mobile/ember-cordova/cordova/res/screen/android/land-xxhdpi.png
delete mode 100644 mobile/ember-cordova/cordova/res/screen/android/land-xxxhdpi.png
delete mode 100644 mobile/ember-cordova/cordova/res/screen/android/port-hdpi.png
delete mode 100644 mobile/ember-cordova/cordova/res/screen/android/port-ldpi.png
delete mode 100644 mobile/ember-cordova/cordova/res/screen/android/port-mdpi.png
delete mode 100644 mobile/ember-cordova/cordova/res/screen/android/port-xhdpi.png
delete mode 100644 mobile/ember-cordova/cordova/res/screen/android/port-xxhdpi.png
delete mode 100644 mobile/ember-cordova/cordova/res/screen/android/port-xxxhdpi.png
delete mode 100644 mobile/ember-cordova/cordova/www/.gitkeep
delete mode 100644 mobile/ember-cordova/icon.svg
delete mode 100644 mobile/ember-cordova/splash.svg
delete mode 100644 mobile/package.json
delete mode 100644 mobile/public/assets/images/colormap.png
delete mode 100644 mobile/public/assets/images/huegasm.png
delete mode 100644 mobile/public/assets/images/lights/filled/aura.svg
delete mode 100644 mobile/public/assets/images/lights/filled/beyond_ceiling_pendant_table.svg
delete mode 100644 mobile/public/assets/images/lights/filled/bloom.svg
delete mode 100644 mobile/public/assets/images/lights/filled/br30.svg
delete mode 100644 mobile/public/assets/images/lights/filled/br30_slim.svg
delete mode 100644 mobile/public/assets/images/lights/filled/bridge_v1.svg
delete mode 100644 mobile/public/assets/images/lights/filled/bridge_v2.svg
delete mode 100644 mobile/public/assets/images/lights/filled/ceiling_round.svg
delete mode 100644 mobile/public/assets/images/lights/filled/ceiling_square.svg
delete mode 100644 mobile/public/assets/images/lights/filled/entity.svg
delete mode 100644 mobile/public/assets/images/lights/filled/floor.svg
delete mode 100644 mobile/public/assets/images/lights/filled/go.svg
delete mode 100644 mobile/public/assets/images/lights/filled/gu10.svg
delete mode 100644 mobile/public/assets/images/lights/filled/gu10_perfectfit.svg
delete mode 100644 mobile/public/assets/images/lights/filled/hds.svg
delete mode 100644 mobile/public/assets/images/lights/filled/impulse.svg
delete mode 100644 mobile/public/assets/images/lights/filled/iris.svg
delete mode 100644 mobile/public/assets/images/lights/filled/lightstrip.svg
delete mode 100644 mobile/public/assets/images/lights/filled/motion_sensor.svg
delete mode 100644 mobile/public/assets/images/lights/filled/pendant_oval.svg
delete mode 100644 mobile/public/assets/images/lights/filled/pendant_round.svg
delete mode 100644 mobile/public/assets/images/lights/filled/pendant_square.svg
delete mode 100644 mobile/public/assets/images/lights/filled/phoenix_ceiling.svg
delete mode 100644 mobile/public/assets/images/lights/filled/phoenix_down.svg
delete mode 100644 mobile/public/assets/images/lights/filled/recessed.svg
delete mode 100644 mobile/public/assets/images/lights/filled/storylight.svg
delete mode 100644 mobile/public/assets/images/lights/filled/table.svg
delete mode 100644 mobile/public/assets/images/lights/filled/tap.svg
delete mode 100644 mobile/public/assets/images/lights/filled/white_and_color_e27.svg
delete mode 100644 mobile/public/assets/images/lights/filled/white_e27.svg
delete mode 100644 mobile/public/assets/images/lights/outline/aura.svg
delete mode 100644 mobile/public/assets/images/lights/outline/beyond_ceiling_pendant_table.svg
delete mode 100644 mobile/public/assets/images/lights/outline/bloom.svg
delete mode 100644 mobile/public/assets/images/lights/outline/br30.svg
delete mode 100644 mobile/public/assets/images/lights/outline/br30_slim.svg
delete mode 100644 mobile/public/assets/images/lights/outline/bridge_v1.svg
delete mode 100644 mobile/public/assets/images/lights/outline/bridge_v2.svg
delete mode 100644 mobile/public/assets/images/lights/outline/ceiling_round.svg
delete mode 100644 mobile/public/assets/images/lights/outline/ceiling_square.svg
delete mode 100644 mobile/public/assets/images/lights/outline/entity.svg
delete mode 100644 mobile/public/assets/images/lights/outline/floor.svg
delete mode 100644 mobile/public/assets/images/lights/outline/go.svg
delete mode 100644 mobile/public/assets/images/lights/outline/gu10.svg
delete mode 100644 mobile/public/assets/images/lights/outline/gu10_perfectfit.svg
delete mode 100644 mobile/public/assets/images/lights/outline/hds.svg
delete mode 100644 mobile/public/assets/images/lights/outline/impulse.svg
delete mode 100644 mobile/public/assets/images/lights/outline/iris.svg
delete mode 100644 mobile/public/assets/images/lights/outline/lightstrip.svg
delete mode 100644 mobile/public/assets/images/lights/outline/motion_sensor.svg
delete mode 100644 mobile/public/assets/images/lights/outline/par16.svg
delete mode 100644 mobile/public/assets/images/lights/outline/pendant_oval.svg
delete mode 100644 mobile/public/assets/images/lights/outline/pendant_round.svg
delete mode 100644 mobile/public/assets/images/lights/outline/pendant_square.svg
delete mode 100644 mobile/public/assets/images/lights/outline/phoenix_ceiling.svg
delete mode 100644 mobile/public/assets/images/lights/outline/phoenix_ceiling_2.svg
delete mode 100644 mobile/public/assets/images/lights/outline/phoenix_down.svg
delete mode 100644 mobile/public/assets/images/lights/outline/phoenix_pendant.svg
delete mode 100644 mobile/public/assets/images/lights/outline/phoenix_table.svg
delete mode 100644 mobile/public/assets/images/lights/outline/phoenix_wall.svg
delete mode 100644 mobile/public/assets/images/lights/outline/recessed.svg
delete mode 100644 mobile/public/assets/images/lights/outline/storylight.svg
delete mode 100644 mobile/public/assets/images/lights/outline/table.svg
delete mode 100644 mobile/public/assets/images/lights/outline/tap.svg
delete mode 100644 mobile/public/assets/images/lights/outline/white_and_color_e27.svg
delete mode 100644 mobile/public/assets/images/lights/outline/white_e27.svg
delete mode 100644 mobile/public/assets/images/missingArtwork.png
delete mode 100644 mobile/public/assets/images/sc-white-sm.png
delete mode 100644 mobile/public/assets/images/sc-white.png
delete mode 100644 mobile/public/assets/images/soundcloudUrl.png
delete mode 100644 mobile/vendor/cie-rgb-converter.js
delete mode 100644 mobile/vendor/dancer.js
delete mode 100644 mobile/yarn.lock
diff --git a/mobile/.bowerrc b/mobile/.bowerrc
deleted file mode 100644
index 959e169..0000000
--- a/mobile/.bowerrc
+++ /dev/null
@@ -1,4 +0,0 @@
-{
- "directory": "bower_components",
- "analytics": false
-}
diff --git a/mobile/.editorconfig b/mobile/.editorconfig
deleted file mode 100644
index 219985c..0000000
--- a/mobile/.editorconfig
+++ /dev/null
@@ -1,20 +0,0 @@
-# EditorConfig helps developers define and maintain consistent
-# coding styles between different editors and IDEs
-# editorconfig.org
-
-root = true
-
-
-[*]
-end_of_line = lf
-charset = utf-8
-trim_trailing_whitespace = true
-insert_final_newline = true
-indent_style = space
-indent_size = 2
-
-[*.hbs]
-insert_final_newline = false
-
-[*.{diff,md}]
-trim_trailing_whitespace = false
diff --git a/mobile/.ember-cli b/mobile/.ember-cli
deleted file mode 100644
index b4934f3..0000000
--- a/mobile/.ember-cli
+++ /dev/null
@@ -1,10 +0,0 @@
-{
- /**
- Ember CLI sends analytics information by default. The data is completely
- anonymous, but there are times when you might want to disable this behavior.
-
- Setting `disableAnalytics` to true will prevent any data from being sent.
- */
- "disableAnalytics": true,
- "usePods": true
-}
diff --git a/mobile/.gitignore b/mobile/.gitignore
deleted file mode 100644
index 905f716..0000000
--- a/mobile/.gitignore
+++ /dev/null
@@ -1,26 +0,0 @@
-# See http://help.github.com/ignore-files/ for more about ignoring files.
-
-# compiled output
-/dist
-/tmp
-
-# dependencies
-/node_modules
-/bower_components
-
-# misc
-/.sass-cache
-/connect.lock
-/coverage/*
-/libpeerconnection.log
-npm-debug.log
-testem.log
-/.idea/
-
-ember-cordova/tmp-livereload
-ember-cordova/cordova/www/*
-!ember-cordova/cordova/www/.gitkeep
-ember-cordova/cordova/plugins/*
-!ember-cordova/cordova/plugins/.gitkeep
-ember-cordova/cordova/platforms/*
-!ember-cordova/cordova/platforms/.gitkeep
diff --git a/mobile/.jshintrc b/mobile/.jshintrc
deleted file mode 100644
index 9f82dad..0000000
--- a/mobile/.jshintrc
+++ /dev/null
@@ -1,38 +0,0 @@
-{
- "predef": [
- "document",
- "window",
- "-Promise",
- "Dancer",
- "ID3",
- "FileAPIReader",
- "SC",
- "introJs",
- "Ps"
- ],
- "browser": true,
- "boss": true,
- "curly": true,
- "debug": false,
- "devel": true,
- "eqeqeq": true,
- "evil": true,
- "forin": false,
- "immed": false,
- "laxbreak": false,
- "newcap": true,
- "noarg": true,
- "noempty": false,
- "nonew": false,
- "nomen": false,
- "onevar": false,
- "plusplus": false,
- "regexp": false,
- "undef": true,
- "sub": true,
- "strict": false,
- "white": false,
- "eqnull": true,
- "esversion": 6,
- "unused": true
-}
diff --git a/mobile/.travis.yml b/mobile/.travis.yml
deleted file mode 100644
index a75f20e..0000000
--- a/mobile/.travis.yml
+++ /dev/null
@@ -1,24 +0,0 @@
----
-language: node_js
-node_js:
- - "4"
-
-sudo: false
-
-cache:
- directories:
- - $HOME/.npm
- - $HOME/.cache # includes bowers cache
-
-before_install:
- - npm config set spin false
- - npm install -g bower phantomjs-prebuilt
- - bower --version
- - phantomjs --version
-
-install:
- - npm install
- - bower install
-
-script:
- - npm test
diff --git a/mobile/.watchmanconfig b/mobile/.watchmanconfig
deleted file mode 100644
index 004881c..0000000
--- a/mobile/.watchmanconfig
+++ /dev/null
@@ -1 +0,0 @@
-{"ignore_dirs":["tmp","dist","ember-cordova"]}
diff --git a/mobile/README.md b/mobile/README.md
deleted file mode 100644
index c8af9d5..0000000
--- a/mobile/README.md
+++ /dev/null
@@ -1,44 +0,0 @@
-# Huegasm
-
-This README outlines the details of collaborating on this Ember application.
-Music awesomeness for hue lights.
-
-## Prerequisites
-
-You will need the following things properly installed on your computer.
-
-* [Git](http://git-scm.com/)
-* [Node.js](http://nodejs.org/) (with NPM)
-* [Bower](http://bower.io/)
-* [Ember CLI](http://ember-cli.com/)
-* [PhantomJS](http://phantomjs.org/)
-
-## Installation
-
-* `git clone ` this repository
-* `cd huegasm`
-* `npm install`
-* `bower install`
-
-## Running / Development
-
-* `ember serve`
-* Visit your app at [http://localhost:4200](http://localhost:4200).
-
-### Code Generators
-
-Make use of the many generators for code, try `ember help generate` for more details
-
-### Building
-
-* `ember build` (development)
-* `ember build --environment production` (production)
-
-## Further Reading / Useful Links
-
-* [ember.js](http://emberjs.com/)
-* [ember-cli](http://ember-cli.com/)
-* Development Browser Extensions
- * [ember inspector for chrome](https://chrome.google.com/webstore/detail/ember-inspector/bmdblncegkenkacieihfhpjfppoconhi)
- * [ember inspector for firefox](https://addons.mozilla.org/en-US/firefox/addon/ember-inspector/)
-
diff --git a/mobile/app/app.js b/mobile/app/app.js
deleted file mode 100644
index 831ad61..0000000
--- a/mobile/app/app.js
+++ /dev/null
@@ -1,18 +0,0 @@
-import Ember from 'ember';
-import Resolver from './resolver';
-import loadInitializers from 'ember-load-initializers';
-import config from './config/environment';
-
-let App;
-
-Ember.MODEL_FACTORY_INJECTIONS = true;
-
-App = Ember.Application.extend({
- modulePrefix: config.modulePrefix,
- podModulePrefix: config.podModulePrefix,
- Resolver
-});
-
-loadInitializers(App, config.modulePrefix);
-
-export default App;
diff --git a/mobile/app/index.html b/mobile/app/index.html
deleted file mode 100644
index 09229fb..0000000
--- a/mobile/app/index.html
+++ /dev/null
@@ -1,30 +0,0 @@
-
-
-
-
-
-
- Huegasm
-
-
-
- {{content-for 'head'}}
-
-
-
-
- {{content-for 'head-footer'}}
-
-
-
-
-
- {{content-for 'body'}}
-
-
-
-
- {{content-for 'body-footer'}}
-
-
-
\ No newline at end of file
diff --git a/mobile/app/pods/application/template.hbs b/mobile/app/pods/application/template.hbs
deleted file mode 100644
index d53e9c5..0000000
--- a/mobile/app/pods/application/template.hbs
+++ /dev/null
@@ -1 +0,0 @@
-{{huegasm-app}}
\ No newline at end of file
diff --git a/mobile/app/pods/components/bridge-finder/component.js b/mobile/app/pods/components/bridge-finder/component.js
deleted file mode 100644
index 9c6e7ac..0000000
--- a/mobile/app/pods/components/bridge-finder/component.js
+++ /dev/null
@@ -1,167 +0,0 @@
-import Ember from 'ember';
-
-const {
- Component,
- observer,
- computed,
- on,
- isNone,
- run: { later },
- $,
- String: { htmlSafe }
-} = Ember;
-
-export default Component.extend({
- elementId: 'bridge-finder',
- classNames: ['container'],
- bridgeIp: null,
- trial: false,
- bridgeUsername: null,
- bridgeFindStatus: null,
- bridgeFindSuccess: computed.equal('bridgeFindStatus', 'success'),
- bridgeFindMultiple: computed.equal('bridgeFindStatus', 'multiple'),
- bridgeFindFail: computed.equal('bridgeFindStatus', 'fail'),
- bridgeUsernamePingMaxTime: 30000, // 30 seconds
- bridgeUsernamePingIntervalTime: 1500,
- bridgeUserNamePingIntervalProgress: 0,
- bridgePingIntervalHandle: null,
- manualBridgeIp: null,
- manualBridgeIpNotFound: false,
- multipleBridgeIps: [],
- isAuthenticating: computed.notEmpty('bridgePingIntervalHandle'),
-
- // try to authenticate against the bridge here
- onBridgeIpChange: on('init', observer('bridgeIp', function () {
- if (!this.get('trial') && !this.get('isAuthenticating')) {
- this.setProperties({
- bridgePingIntervalHandle: setInterval(this.pingBridgeUser.bind(this), this.get('bridgeUsernamePingIntervalTime')),
- bridgeUserNamePingIntervalProgress: 0
- });
- }
- })),
-
- didInsertElement() {
- $(document).keypress((event) => {
- if (!isNone(this.get('manualBridgeIp')) && event.which === 13) {
- this.send('findBridgeByIp');
- }
- });
-
- document.addEventListener('resume', () => {
- if (this.get('trial') || this.get('bridgeFindFail')) {
- this.send('tryAgain');
- }
- }, false);
- },
-
- // find the bridge ip here
- init() {
- this._super(...arguments);
-
- if (this.get('bridgeIp') === null) {
- $.ajax('https://www.meethue.com/api/nupnp', {
- timeout: 30000
- })
- .done((result, status) => {
- let bridgeFindStatus = 'fail';
-
- if (status === 'success' && result.length === 1) {
- this.set('bridgeIp', result[0].internalipaddress);
- this.get('storage').set('huegasm.bridgeIp', result[0].internalipaddress);
- bridgeFindStatus = 'success';
- } else if (result.length > 1) {
- let multipleBridgeIps = this.get('multipleBridgeIps');
-
- result.forEach(function (item) {
- multipleBridgeIps.pushObject(item.internalipaddress);
- });
-
- bridgeFindStatus = 'multiple';
- } else {
- bridgeFindStatus = 'fail';
- }
-
- this.set('bridgeFindStatus', bridgeFindStatus);
- })
- .fail(() => {
- this.set('bridgeFindStatus', 'fail');
- });
- }
- },
-
- pingBridgeUser() {
- let bridgeIp = this.get('bridgeIp'),
- bridgeUserNamePingIntervalProgress = this.get('bridgeUserNamePingIntervalProgress'),
- bridgeUsernamePingMaxTime = this.get('bridgeUsernamePingMaxTime');
-
- if (bridgeIp !== null && bridgeUserNamePingIntervalProgress < 100) {
- $.ajax('http://' + bridgeIp + '/api', {
- data: JSON.stringify({ "devicetype": "huegasm" }),
- contentType: 'application/json',
- type: 'POST'
- }).done((result, status) => {
- if (!this.isDestroyed) {
- if (status === 'success' && !result[0].error) {
- this.clearBridgePingIntervalHandle();
- this.get('storage').set('huegasm.bridgeUsername', result[0].success.username);
- this.set('bridgeUsername', result[0].success.username);
- }
- }
- }).fail(() => {
- this.clearBridgePingIntervalHandle();
- this.setProperties({
- bridgeConnectError: true,
- bridgeConnectMessage: htmlSafe('Your network and/or system security settings are preventing Huegasm from connecting to your Hue bridge.' +
- 'Feel free to contact us at huegasm.app@gmail.com if this is unexpected and you need help debugging the problem. ')
- })
- });
-
- this.incrementProperty('bridgeUserNamePingIntervalProgress', this.get('bridgeUsernamePingIntervalTime') / bridgeUsernamePingMaxTime * 100);
- } else {
- this.clearBridgePingIntervalHandle();
- }
- },
-
- clearBridgePingIntervalHandle() {
- clearInterval(this.get('bridgePingIntervalHandle'));
- this.set('bridgePingIntervalHandle', null);
- },
-
- actions: {
- tryAgain() {
- this.get('storage').clear();
- location.reload();
- },
- retry() {
- this.onBridgeIpChange();
- },
- chooseBridge(bridge) {
- this.set('bridgeIp', bridge);
- this.get('storage').set('huegasm.bridgeIp', bridge);
- },
- findBridgeByIp() {
- let manualBridgeIp = this.get('manualBridgeIp');
-
- if (manualBridgeIp.toLowerCase() === 'trial' || manualBridgeIp.toLowerCase() === 'offline') {
- this.setProperties({
- trial: true,
- bridgeIp: 'trial',
- bridgeUsername: 'trial'
- });
- } else {
- $.ajax('http://' + manualBridgeIp + '/api', {
- data: JSON.stringify({ "devicetype": "huegasm" }),
- contentType: 'application/json',
- type: 'POST'
- }).fail(() => {
- this.set('manualBridgeIpNotFound', true);
- later(this, function () {
- this.set('manualBridgeIpNotFound', false);
- }, 5000);
- }).then(() => {
- this.send('chooseBridge', manualBridgeIp);
- });
- }
- }
- },
-});
diff --git a/mobile/app/pods/components/bridge-finder/template.hbs b/mobile/app/pods/components/bridge-finder/template.hbs
deleted file mode 100644
index 22f4760..0000000
--- a/mobile/app/pods/components/bridge-finder/template.hbs
+++ /dev/null
@@ -1,81 +0,0 @@
-{{#unless bridgeUsername}}
- {{#if bridgeIp}}
- {{#unless bridgeConnectError}}
-
-
-
-
-
-
-
-
-
- {{paper-progress-linear warn=true value=bridgeUserNamePingIntervalProgress}}
- {{/unless}}
-
-
- {{#if isAuthenticating}}
- Your bridge IP is {{bridgeIp}}
- Press the button on your bridge to authenticate Huegasm.
- {{else}}
- {{#if bridgeConnectError}}
- {{bridgeConnectMessage}}
- {{else}}
-
You failed to press the button in time. RETRY
- {{/if}}
- {{/if}}
-
- {{else}}
- {{#unless bridgeFindStatus}}
- {{paper-progress-circular diameter=100}}
- Trying to find your bridge's IP.
- {{/unless}}
-
- {{#if bridgeFindMultiple}}
- Huegasm found multiple hue bridges. Please select the one you want to use for Huegasm.
-
-
- {{#each multipleBridgeIps as |bridge|}}
- {{paper-radio value=bridge label=bridge onChange=(action "chooseBridge")}}
- {{/each}}
-
- {{else}}
- {{#if bridgeFindFail}}
- A hue bridge could not be automatically found on your network. Enter one manually? (or type offline to look around)
-
-
-
- {{paper-input label="Hue bridge IP address" value=manualBridgeIp onChange=(action (mut manualBridgeIp))}}
-
-
- {{paper-button onClick=(action "findBridgeByIp") raised=true primary=true label="Find"}}
-
-
-
- {{#if manualBridgeIpNotFound}}
-
- Could not find a bridge with that IP address.
-
- {{/if}}
- {{/if}}
- {{/if}}
- {{/if}}
-{{/unless}}
\ No newline at end of file
diff --git a/mobile/app/pods/components/hue-controls/component.js b/mobile/app/pods/components/hue-controls/component.js
deleted file mode 100644
index 55afc40..0000000
--- a/mobile/app/pods/components/hue-controls/component.js
+++ /dev/null
@@ -1,265 +0,0 @@
-import Ember from 'ember';
-
-const {
- A,
- Component,
- computed,
- isNone,
- inject,
- run: { later },
- $
-} = Ember;
-
-export default Component.extend({
- classNames: ['container-fluid'],
- elementId: 'hue-controls',
- lightsData: null,
-
- activeLights: A(),
- tabList: ["Lights", "Music"],
- selectedTab: 1,
- pauseLightUpdates: false,
-
- dimmerOn: false,
- lightsIconsOn: true,
- playing: false,
-
- displayFailure: true,
-
- notify: inject.service(),
-
- dimmerOnClass: computed('dimmerOn', function(){
- let dimmerOn = this.get('dimmerOn'),
- storage = this.get('storage'),
- dimmerOnClass = 'md-menu-origin';
-
- if (dimmerOn) {
- $('body').addClass('dimmerOn');
- $('html').addClass('dimmerOn');
- dimmerOnClass += ' dimmerOn';
- } else {
- $('body').removeClass('dimmerOn');
- $('html').removeClass('dimmerOn');
- }
-
- storage.set('huegasm.dimmerOn', dimmerOn);
-
- return dimmerOnClass;
- }),
-
- ready: computed('lightsData', 'trial', function() {
- return this.get('trial') || !isNone(this.get('lightsData'));
- }),
-
- apiURL: computed('bridgeIp', 'bridgeUsername', function(){
- return 'http://' + this.get('bridgeIp') + '/api/' + this.get('bridgeUsername');
- }),
-
- tabData: computed('tabList', 'selectedTab', function(){
- let tabData = [], selectedTab = this.get('selectedTab');
-
- this.get('tabList').forEach(function(tab, i){
- let selected = false;
-
- if(i === selectedTab){
- selected = true;
- }
-
- tabData.push({"name": tab, "selected": selected });
- });
-
- return tabData;
- }),
-
- init() {
- this._super(...arguments);
-
- let storage = this.get('storage');
-
- if(!this.get('trial')) {
- this.updateLightData();
- setInterval(this.updateLightData.bind(this), 2000);
- }
-
- if (!isNone(storage.get('huegasm.dimmerOn'))) {
- this.set('dimmerOn', storage.get('huegasm.dimmerOn'));
- this.get('dimmerOnClass');
- }
-
- if (!isNone(storage.get('huegasm.lightsIconsOn'))) {
- this.set('lightsIconsOn', storage.get('huegasm.lightsIconsOn'));
- }
-
- if (!isNone(this.get('storage').get('huegasm.selectedTab'))) {
- this.set('selectedTab', this.get('storage').get('huegasm.selectedTab'));
- }
-
- document.addEventListener('backbutton', () => {
- if(this.get('isShowingAddSoundCloudModal')){
- this.set('isShowingAddSoundCloudModal', false);
- } else {
- let index = (this.get('selectedTab') + 1) % this.tabList.length;
- this.set('selectedTab', index);
- this.get('storage').set('huegasm.selectedTab', index);
- }
- }, false);
-
- document.addEventListener('pause', () => {
- this.set('pauseLightUpdates', true);
- }, false);
-
- document.addEventListener('resume', () => {
- this.set('pauseLightUpdates', false);
- }, false);
- },
-
- updateLightData(){
- let fail = ()=>{
- if(isNone(this.get('lightsData'))) {
- this.send('clearBridge');
- } else if(this.get('displayFailure')) {
- this.get('notify').warning({html: 'Error retrieving data from your lights. Yikes.
'});
- this.set('displayFailure', false);
-
- later(this, () => {
- this.set('displayFailure', true);
- }, 30000);
- }
- };
-
- if(!this.get('pauseLightUpdates')){
- $.get(this.get('apiURL') + '/lights', (result, status)=>{
- if(!isNone(result[0]) && !isNone(result[0].error)){
- fail();
- } else if (status === 'success' && JSON.stringify(this.get('lightsData')) !== JSON.stringify(result)) {
- this.set('lightsData', result);
- }
- }).fail(fail);
- }
- },
-
- actions: {
- changeTab(tabName){
- let index = this.get('tabList').indexOf(tabName);
- this.set('selectedTab', index);
- this.get('storage').set('huegasm.selectedTab', index);
- },
- clearBridge() {
- let storage = this.get('storage');
- storage.remove('huegasm.bridgeUsername');
- storage.remove('huegasm.bridgeIp');
- location.reload();
- },
- clearAllSettings() {
- this.get('storage').clear();
- location.reload();
- },
- startIntro(){
- let intro = introJs();
-
- if(this.get('dimmerOn')) {
- this.send('toggleDimmer');
- }
-
- intro.setOptions({
- steps: [
- {
- intro: 'Welcome! This short tutorial will introduce you to Huegasm.'
- },
- {
- element: '#music-tab',
- intro: 'This is the music player. You\'ll use this to play music and synchronize it with your active lights. ' +
- 'TIP : Control which lights are active through the Lights tab. '
- },
- {
- element: '#playlist',
- intro: 'You can add and select music to play from your playlist here. You may listen to local audio files or stream music from Soundcloud. ' +
- 'TIP : Songs added through Soundcloud will be saved for when you visit this page again. '
- },
- {
- element: $('#playlist md-menu')[0],
- intro: ' You can add songs from SoundCloud by copy and pasting the URL shown here'
- },
- {
- element: '#player-area',
- intro: 'The audio playback may be controlled with the controls here. Basic music visualization effects may be shown here by selecting them from the menu (eyeball icon in the bottom right).'
- },
- {
- element: '#beat-option-row',
- intro: 'These are the settings for the music tab: ' +
- 'Sensitivity - The sensitivity of the beat detector (more sensitivity results in more registered beats) ' +
- 'Hue Range - The hue range that the lights may change to on beat. ' +
- 'Brightness Range - The minimum (off-beat) and maximum (on-beat) brightness of the lights. ' +
- 'Flashing Transitions - Quickly flash the lights on beat ' +
- 'Colorloop - Slowly cycle the lights through all the colors while the music is playing ' +
- 'TIP : Your sensitivity settings are saved per song as indicated by the red star icon in the top left corner. These settings they will be restored if you ever listen to the same song again. ',
- position: 'top'
- },
- {
- element: '#lights-tab',
- intro: 'This is the lights tab. Here you\'ll be able to change various light properties: ' +
- 'Power - Turn the selected lights on/off ' +
- 'Brightness - The brightness level of the selected lights ' +
- 'Color - The color of the selected lights ' +
- 'Strobe - Selected lights will flash in sequential order ' +
- 'Colorloop - Selected lights will slowly cycle through all the colors '
- },
- {
- element: '#active-lights',
- intro: 'These icons represent the hue lights in your system. Active lights will be controlled by the application while the inactive lights will have a red X over them and will not be controlled. ' +
- 'You may toggle a light\'s state by clicking on it.'
- },
- {
- element: $('#navigation .ember-basic-dropdown-trigger')[0],
- intro: 'A few miscellaneous settings can be found here. ' +
- 'WARNING : clearing application settings will restore the application to its original state. This will even delete your playlist and any saved song beat preferences.'
- },
- {
- intro: 'And that\'s it...Hope you enjoy the application. ;)'
- }
- ]
- });
-
- intro.onexit(() => {
- $('body').velocity('scroll', { duration: 200 });
- });
-
- // it's VERY ugly but it works... the jQuery massacre :'(
- intro.onchange((element) => {
- if(element.id === '' || element.id === 'music-tab' || element.id === 'playlist' || element.id === 'player-area' || element.id === 'beat-option-row' || element.id === 'beat-option-button-group' || element.id === 'using-mic-audio-tooltip' || element.nodeName === 'MD-MENU'){
- $('.navigation-item').eq(1).click();
- } else {
- $('.navigation-item').eq(0).click();
- }
- });
-
- // skip hidden/missing elements
- intro.onafterchange((element)=>{
- let elem = $(element);
- if(elem.html() === '') {
- $('.introjs-nextbutton').click();
- }
-
- if(element.id === ''){
- later(this, () => {
- $('body').velocity('scroll');
- }, 500);
- } else {
- later(this, () => {
- $('.introjs-tooltip').velocity('scroll', { offset: -100 });
- }, 500);
- }
- }).start();
- },
- toggleDimmer(){
- this.toggleProperty('dimmerOn');
- },
- toggleLightsIcons() {
- this.toggleProperty('lightsIconsOn');
-
- let lightsIconsOn = this.get('lightsIconsOn');
-
- this.get('storage').set('huegasm.lightsIconsOn', lightsIconsOn);
- }
- }
-});
diff --git a/mobile/app/pods/components/hue-controls/template.hbs b/mobile/app/pods/components/hue-controls/template.hbs
deleted file mode 100644
index bee6a2a..0000000
--- a/mobile/app/pods/components/hue-controls/template.hbs
+++ /dev/null
@@ -1,49 +0,0 @@
-{{#if ready}}
-
- {{#each tabData as |tab|}}
- {{tab.name}}
- {{/each}}
-
- {{#paper-menu as |menu|}}
- {{#menu.trigger}}
- {{#paper-button iconButton=true}}
- {{paper-icon "settings-icon" class=dimmerOnClass size=28}}
- {{/paper-button}}
- {{/menu.trigger}}
- {{#menu.content width=3 as |content|}}
- {{#content.menu-item onClick="toggleDimmer"}}
- {{paper-icon "highlight" class=dimmerOnClass}} Dark Mode: {{if dimmerOn "On" "Off"}}
- {{/content.menu-item}}
-
- {{#content.menu-item onClick="toggleLightsIcons"}}
- {{paper-icon "lightbulb outline" class=dimmerOnClass}} Active Lights: {{if lightsIconsOn "Icons" "Text"}}
- {{/content.menu-item}}
-
- {{#content.menu-item onClick="clearBridge"}}
- {{paper-icon "compare arrows" class=dimmerOnClass}} Switch bridge
- {{/content.menu-item}}
-
- {{#content.menu-item onClick="startIntro"}}
- {{paper-icon "cached" class=dimmerOnClass}} Restart tutorial
- {{/content.menu-item}}
-
- {{#content.menu-item onClick="clearAllSettings"}}
- {{paper-icon "settings backup restore" class=dimmerOnClass}} Reset settings
- {{/content.menu-item}}
- {{/menu.content}}
- {{/paper-menu}}
-
-
-
- {{light-group lightsData=lightsData activeLights=activeLights syncLight=syncLight apiURL=apiURL dimmerOn=dimmerOn lightsIconsOn=lightsIconsOn storage=storage}}
-
-
- {{lights-tab active=(eq selectedTab 0) apiURL=apiURL lightsData=lightsData activeLights=activeLights syncLight=syncLight trial=trial colorLoopOn=colorLoopOn dimmerOn=dimmerOn playing=playing pauseLightUpdates=pauseLightUpdates}}
-
- {{music-tab active=(eq selectedTab 1) apiURL=apiURL lightsData=lightsData activeLights=activeLights pauseLightUpdates=pauseLightUpdates dimmerOn=dimmerOn playing=playing storage=storage colorLoopOn=colorLoopOn isShowingAddSoundCloudModal=isShowingAddSoundCloudModal action="startIntro"}}
-
-{{else}}
- {{paper-progress-circular diameter=100}}
-{{/if}}
-
-{{ember-notify messageStyle='bootstrap' closeAfter=5000}}
\ No newline at end of file
diff --git a/mobile/app/pods/components/huegasm-app/component.js b/mobile/app/pods/components/huegasm-app/component.js
deleted file mode 100644
index e065054..0000000
--- a/mobile/app/pods/components/huegasm-app/component.js
+++ /dev/null
@@ -1,27 +0,0 @@
-import Ember from 'ember';
-
-const {
- Component,
- isEmpty
-} = Ember;
-
-export default Component.extend({
- bridgeIp: null,
- bridgeUsername: null,
- trial: false,
- storage: null,
-
- init() {
- this._super(...arguments);
-
- let storage = new window.Locally.Store({ compress: true });
- this.set('storage', storage);
-
- if (!isEmpty(storage.get('huegasm.bridgeIp')) && !isEmpty(storage.get('huegasm.bridgeUsername'))) {
- this.setProperties({
- bridgeIp: storage.get('huegasm.bridgeIp'),
- bridgeUsername: storage.get('huegasm.bridgeUsername')
- });
- }
- }
-});
diff --git a/mobile/app/pods/components/huegasm-app/template.hbs b/mobile/app/pods/components/huegasm-app/template.hbs
deleted file mode 100644
index 144e86b..0000000
--- a/mobile/app/pods/components/huegasm-app/template.hbs
+++ /dev/null
@@ -1,5 +0,0 @@
-{{#if bridgeUsername}}
- {{hue-controls bridgeIp=bridgeIp bridgeUsername=bridgeUsername trial=trial storage=storage}}
-{{else}}
- {{bridge-finder bridgeIp=bridgeIp bridgeUsername=bridgeUsername trial=trial storage=storage}}
-{{/if}}
\ No newline at end of file
diff --git a/mobile/app/pods/components/light-group/component.js b/mobile/app/pods/components/light-group/component.js
deleted file mode 100644
index a77593c..0000000
--- a/mobile/app/pods/components/light-group/component.js
+++ /dev/null
@@ -1,213 +0,0 @@
-import Ember from 'ember';
-
-const {
- A,
- Component,
- computed,
- isNone,
- observer
-} = Ember;
-
-export default Component.extend({
- elementId: 'active-lights',
- classNames: ['light-group'],
- activeLights: A(),
-
- // list of all the lights in the hue system
- lightsList: computed('lightsData', 'activeLights.[]', 'dimmerOn', function(){
- let lightsData = this.get('lightsData'),
- activeLights = this.get('activeLights'),
- dimmerOn = this.get('dimmerOn'),
- lightsList = A(),
- src,
- activeClass;
-
- for (let key in lightsData) {
- activeClass = 'light-active';
-
- if (lightsData.hasOwnProperty(key) && lightsData[key].state.reachable) {
- switch (lightsData[key].modelid) {
- case 'BSB001':
- src = 'bridge_v1';
- break;
- case 'BSB002':
- src = 'bridge_v2';
- break;
- case 'LCT001':
- case 'LCT007':
- case 'LCT010':
- case 'LCT014':
- case 'LTW010':
- case 'LTW001':
- case 'LTW004':
- case 'LTW015':
- case 'LWB004':
- case 'LWB006':
- src = 'white_and_color_e27';
- break;
- case 'LWB010':
- case 'LWB014':
- src = 'white_e27';
- break;
- case 'LCT002':
- src = 'br30';
- break;
- case 'LCT011':
- case 'LTW011':
- src = 'br30_slim';
- break;
- case 'LCT003':
- src = 'gu10';
- break;
- case 'LTW013':
- src = 'gu10_perfectfit';
- break;
- case 'LST002':
- case 'LST001':
- src = 'lightstrip';
- break;
- case 'LLC006':
- case 'LLC010':
- src = 'iris';
- break;
- case 'LLC005':
- case 'LLC011':
- case 'LLC012':
- case 'LLC007':
- src = 'bloom';
- break;
- case 'LLC014':
- src = 'aura';
- break;
- case 'LLC013':
- src = 'storylight';
- break;
- case 'LLC020':
- src = 'go';
- break;
- case 'HBL001':
- case 'HBL002':
- case 'HBL003':
- src = 'beyond_ceiling_pendant_table';
- break;
- case 'HIL001':
- case 'HIL002':
- src = 'impulse';
- break;
- case 'HEL001':
- case 'HEL002':
- src = 'entity';
- break;
- case 'HML001':
- case 'HML002':
- case 'HML003':
- case 'HML004':
- case 'HML005':
- src = 'phoenix_ceiling';
- break;
- case 'HML006':
- src = 'phoenix_down';
- break;
- case 'LTP003':
- src = 'pendant_square';
- break;
- case 'LTP002':
- case 'LTP003':
- src = 'pendant_round';
- break;
- case 'LTP001':
- src = 'pendant_oval';
- break;
- case 'LDF002':
- case 'LTF002':
- case 'LTF001':
- case 'LTC001':
- case 'LTC002':
- case 'LDF001':
- src = 'ceiling_square';
- break;
- case 'LTC003':
- case 'LTD001':
- case 'LTD001':
- src = 'ceiling_round';
- break;
- case 'LDD002':
- src = 'floor';
- break;
- case 'LDD001':
- src = 'table';
- break;
- case 'LDT001':
- case 'MWM001':
- src = 'recessed';
- break;
- case 'SWT001':
- src = 'tap';
- break;
- case 'RWL021':
- src = 'hds';
- break;
- case 'SML001':
- src = 'motion_sensor';
- break;
- default:
- src = 'white_e27';
- }
-
- if (dimmerOn) {
- src = `assets/images/lights/filled/${src}.svg`;
- } else {
- src = `assets/images/lights/outline/${src}.svg`;
- }
-
- if(!activeLights.includes(key)){
- activeClass = 'light-inactive';
- }
-
- lightsList.push({ src, name: lightsData[key].name, id: key, data: lightsData[key], activeClass });
- }
- }
-
- return lightsList;
- }),
-
- onActiveLightsChange: observer('activeLights.[]', function(){
- this.get('storage').set('huegasm.activeLights', this.get('activeLights'));
- }),
-
- init(){
- this._super(...arguments);
-
- let lightsData = this.get('lightsData'),
- activeLights = this.get('activeLights'),
- activeLightsCache = this.get('storage').get('huegasm.activeLights');
-
- if(!isNone(activeLightsCache)){
- activeLightsCache.forEach(function(i){
- if (!isNone(lightsData) && lightsData.hasOwnProperty(i) && lightsData[i].state.reachable) {
- activeLights.pushObject(i);
- }
- });
- } else {
- for (let key in lightsData) {
- if (lightsData.hasOwnProperty(key) && lightsData[key].state.reachable) {
- activeLights.pushObject(key);
- }
- }
- }
- },
-
- actions: {
- clickLight(id){
- let activeLights = this.get('activeLights'),
- lightId = activeLights.indexOf(id);
-
- if(lightId !== -1){
- activeLights.removeObject(id);
- } else {
- activeLights.pushObject(id);
- this.set('syncLight', id);
- }
- }
- }
-});
diff --git a/mobile/app/pods/components/light-group/template.hbs b/mobile/app/pods/components/light-group/template.hbs
deleted file mode 100644
index 05c41de..0000000
--- a/mobile/app/pods/components/light-group/template.hbs
+++ /dev/null
@@ -1,11 +0,0 @@
-{{#each lightsList as |light|}}
- {{#if lightsIconsOn}}
-
- {{inline-svg light.src class="hue-light"}}
-
- {{else}}
-
- {{/if}}
-{{/each}}
\ No newline at end of file
diff --git a/mobile/app/pods/components/lights-tab/color-picker/component.js b/mobile/app/pods/components/lights-tab/color-picker/component.js
deleted file mode 100644
index 232cfb1..0000000
--- a/mobile/app/pods/components/lights-tab/color-picker/component.js
+++ /dev/null
@@ -1,58 +0,0 @@
-import Ember from 'ember';
-
-const {
- Component,
- $
-} = Ember;
-
-export default Component.extend({
- elementId: 'color-picker',
- rgb: null,
- canvas: null,
- canvasContext: null,
- pressingDown: false,
-
- mouseUp(){
- this.set('pressingDown', false);
- },
-
- mouseMove(event){
- if (this.get('pressingDown')) {
- this.mouseDown(event);
- }
- },
-
- mouseDown(event){
- let canvasOffset = $(this.get('canvas')).offset(),
- canvasX = Math.floor(event.pageX - canvasOffset.left),
- canvasY = Math.floor(event.pageY - canvasOffset.top);
-
- // get current pixel
- let imageData = this.get('canvasContext').getImageData(canvasX, canvasY, 1, 1),
- pixel = imageData.data;
-
- this.set('pressingDown', true);
-
- if (!(pixel[0] === 0 && pixel[1] === 0 && pixel[2] === 0)) {
- this.set('rgb', [pixel[0], pixel[1], pixel[2]]);
- }
- },
-
- // https://dzone.com/articles/creating-your-own-html5
- didInsertElement(){
- // handle color changes
- let canvas = $('#picker')[0],
- canvasContext = canvas.getContext('2d'),
- image = new Image();
-
- image.src = 'assets/images/colormap.png';
- image.onload = function () {
- canvasContext.drawImage(image, 0, 0, image.width, image.height); // draw the image on the canvas
- };
-
- this.setProperties({
- canvas: canvas,
- canvasContext: canvasContext
- });
- }
-});
diff --git a/mobile/app/pods/components/lights-tab/color-picker/template.hbs b/mobile/app/pods/components/lights-tab/color-picker/template.hbs
deleted file mode 100644
index 16508e9..0000000
--- a/mobile/app/pods/components/lights-tab/color-picker/template.hbs
+++ /dev/null
@@ -1 +0,0 @@
-
\ No newline at end of file
diff --git a/mobile/app/pods/components/lights-tab/component.js b/mobile/app/pods/components/lights-tab/component.js
deleted file mode 100644
index d9beaec..0000000
--- a/mobile/app/pods/components/lights-tab/component.js
+++ /dev/null
@@ -1,278 +0,0 @@
-import Ember from 'ember';
-
-const {
- Component,
- observer,
- computed,
- on,
- run: { later, once },
- $
-} = Ember;
-
-export default Component.extend({
- classNames: ['col-xs-12'],
- classNameBindings: ['active::hidden'],
- elementId: 'lights-tab',
-
- rgb: [255, 255, 255],
-
- lightsOn: false,
-
- colorLoopOn: false,
-
- lightsOnTxt: computed('lightsOn', function () {
- return this.get('lightsOn') ? 'On' : 'Off';
- }),
-
- colorloopOnTxt: computed('colorLoopOn', function () {
- return this.get('colorLoopOn') ? 'On' : 'Off';
- }),
-
- // determines the average brightness of the hue system for the brightness slider
- lightsBrightness: computed('lightsData', 'activeLights.[]', function () {
- let lightsData = this.get('lightsData'),
- activeLights = this.get('activeLights'),
- lightsBrightness = 0;
-
- activeLights.forEach(function (light) {
- lightsBrightness += lightsData[light].state.bri;
- });
-
- return lightsBrightness / activeLights.length;
- }),
-
- brightnessControlDisabled: computed.not('lightsOn'),
-
- onColorLoopOnChange: observer('colorLoopOn', function () {
- let lightsData = this.get('lightsData'),
- activeLights = this.get('activeLights'),
- colorLoopsOn = this.get('colorLoopOn'),
- effect = colorLoopsOn ? 'colorloop' : 'none';
-
- let colorLoopsOnSystem = activeLights.some(function (light) {
- return lightsData[light].state.effect === 'colorloop';
- });
-
- // if the internal lights state is different than the one from lightsData (user manually toggled the switch), send the request to change the bulbs state
- if (colorLoopsOn !== colorLoopsOnSystem) {
- activeLights.forEach((light) => {
- if (this.get('lightsData')[light].state.effect !== effect) {
- $.ajax(this.get('apiURL') + '/lights/' + light + '/state', {
- data: JSON.stringify({ 'effect': effect }),
- contentType: 'application/json',
- type: 'PUT'
- });
- }
- });
- }
- }),
-
- rgbPreview: observer('rgb', function () {
- let rgb = this.get('rgb'),
- xy = rgbToCie(rgb[0], rgb[1], rgb[2]);
-
- this.set('colorLoopOn', false);
-
- this.get('activeLights').forEach((light) => {
- $.ajax(this.get('apiURL') + '/lights/' + light + '/state', {
- data: JSON.stringify({ "xy": xy }),
- contentType: 'application/json',
- type: 'PUT'
- });
- });
-
- this.set('colorLoopOn', false);
- $('.color').css('background', 'rgb(' + rgb[0] + ',' + rgb[1] + ',' + rgb[2] + ')');
- }),
-
- onActiveLightsChange: on('init', observer('activeLights.[]', function () {
- let lightsData = this.get('lightsData'),
- xy = null,
- setRGB = true;
-
- this.get('activeLights').forEach((i) => {
- let light = lightsData[i];
-
- if (xy !== null && xy[0] !== light.state.xy[0] && xy[1] !== light.state.xy[1]) {
- setRGB = false;
- }
-
- xy = light.state.xy;
- });
-
- if (setRGB && xy) {
- let rgb = cieToRgb(xy[0], xy[1]);
-
- $('.color').css('background', 'rgb(' + Math.abs(rgb[0]) + ',' + Math.abs(rgb[1]) + ',' + Math.abs(rgb[2]) + ')');
- } else {
- $('.color').css('background', 'rgb(' + 255 + ',' + 255 + ',' + 255 + ')');
- }
- })),
-
- // determines whether the lights are on/off for the lights switch
- lightsOnChange: on('init', observer('lightsData.@each.state.on', 'activeLights.[]', function () {
- if (!this.get('strobeOn')) {
- let lightsData = this.get('lightsData'), lightsOn = this.get('activeLights').some(function (light) {
- return lightsData[light].state.on === true;
- });
-
- this.set('lightsOn', lightsOn);
- }
- })),
-
- onLightsOnChange: observer('lightsOn', function () {
- let lightsData = this.get('lightsData'),
- activeLights = this.get('activeLights'),
- lightsOn = this.get('lightsOn');
-
- let lightsOnSystem = activeLights.some(function (light) {
- return lightsData[light].state.on === true;
- });
-
- // if the internal lights state is different than the one from lightsData (user manually toggled the switch), send the request to change the bulbs state
- if (lightsOn !== lightsOnSystem) {
- activeLights.forEach((light) => {
- $.ajax(this.get('apiURL') + '/lights/' + light + '/state', {
- data: JSON.stringify({ "on": lightsOn }),
- contentType: 'application/json',
- type: 'PUT'
- });
- });
- }
- }),
-
- onBrightnessChanged: observer('lightsBrightness', function () {
- once(this, function () {
- let lightsData = this.get('lightsData'),
- lightsBrightnessSystem = false,
- lightsBrightness = this.get('lightsBrightness'),
- activeLights = this.get('activeLights');
-
- activeLights.forEach(function (light) {
- lightsBrightnessSystem += lightsData[light].state.bri;
- });
-
- lightsBrightnessSystem /= activeLights.length;
-
- // if the internal lights state is different than the one from lightsData (user manually toggled the switch), send the request to change the bulbs state
- if (lightsBrightness !== lightsBrightnessSystem) {
- activeLights.forEach((light) => {
- $.ajax(this.get('apiURL') + '/lights/' + light + '/state', {
- data: JSON.stringify({ "bri": lightsBrightness }),
- contentType: 'application/json',
- type: 'PUT'
- });
- });
- }
- });
- }),
-
- // sync the current light settings to the newly added light
- onaActiveLightsChange: observer('syncLight', function () {
- let options = {
- on: this.get('lightsOn'),
- bri: this.get('lightsBrightness'),
- effect: this.get('colorLoopOn') ? 'colorloop' : 'none'
- }, rgb = this.get('rgb'),
- syncLight = this.get('syncLight');
-
- if (rgb[0] !== 255 && rgb[1] !== 255 && rgb[2] !== 255) {
- options['xy'] = this.rgbToXy(rgb[0], rgb[1], rgb[2]);
- }
-
- options['transitiontime'] = 0;
-
- $.ajax(this.get('apiURL') + '/lights/' + syncLight + '/state', {
- data: JSON.stringify(options),
- contentType: 'application/json',
- type: 'PUT'
- });
- }),
-
- // **************** STROBE LIGHT START ****************
- strobeOn: false,
-
- strobeOnInervalHandle: null,
- preStrobeOnLightsDataCache: null,
- nextLightIdx: 0,
-
- onStrobeOnChange: observer('strobeOn', function () {
- let lightsData = this.get('lightsData'),
- strobeOn = this.get('strobeOn');
-
- if (strobeOn) {
- this.set('preStrobeOnLightsDataCache', lightsData);
- let stobeInitRequestData = { 'transitiontime': 0 };
-
- for (let key in lightsData) {
- if (lightsData.hasOwnProperty(key)) {
- if (lightsData[key].state.on) {
- stobeInitRequestData.on = false;
- }
-
- $.ajax(this.get('apiURL') + '/lights/' + key + '/state', {
- data: JSON.stringify(stobeInitRequestData),
- contentType: 'application/json',
- type: 'PUT'
- });
- }
- }
-
- this.set('strobeOnInervalHandle', setInterval(this.strobeStep.bind(this), 500));
- } else { // revert the light system to pre-strobe
- let preStrobeOnLightsDataCache = this.get('preStrobeOnLightsDataCache'), updateLight = (lightIndex) => {
- $.ajax(this.get('apiURL') + '/lights/' + lightIndex + '/state', {
- data: JSON.stringify({
- 'on': preStrobeOnLightsDataCache[lightIndex].state.on,
- 'sat': preStrobeOnLightsDataCache[lightIndex].state.sat
- }),
- contentType: 'application/json',
- type: 'PUT'
- });
- };
-
- for (let key in lightsData) {
- if (lightsData.hasOwnProperty(key)) {
- later(this, updateLight, key, 2000);
- }
- }
-
- later(this, this.onColorLoopOnChange, 2000);
- clearInterval(this.get('strobeOnInervalHandle'));
- }
-
- this.set('pauseLightUpdates', strobeOn);
- }),
-
- strobeStep() {
- let nextLightIdx = this.get('nextLightIdx') % this.get('activeLights').length,
- nextStrobeLight = this.get('activeLights')[nextLightIdx],
- turnOnOptions = { on: true, transitiontime: 0, alert: 'select' };
-
- // random light if in cololoop mode
- if (this.get('colorLoopOn')) {
- turnOnOptions.hue = Math.floor(Math.random() * 65535);
- }
-
- $.ajax(this.get('apiURL') + '/lights/' + nextStrobeLight + '/state', {
- data: JSON.stringify(turnOnOptions),
- contentType: 'application/json',
- type: 'PUT'
- });
- $.ajax(this.get('apiURL') + '/lights/' + nextStrobeLight + '/state', {
- data: JSON.stringify({ 'on': false, 'transitiontime': 0 }),
- contentType: 'application/json',
- type: 'PUT'
- });
-
- this.set('nextLightIdx', ++nextLightIdx);
- },
-
- strobeOnTxt: computed('strobeOn', function () {
- return this.get('strobeOn') ? 'On' : 'Off';
- }),
-
- dimmerOnClass: computed('dimmerOn', function () {
- return this.get('dimmerOn') ? 'dimmerOn' : null;
- })
-});
diff --git a/mobile/app/pods/components/lights-tab/template.hbs b/mobile/app/pods/components/lights-tab/template.hbs
deleted file mode 100644
index 21377fa..0000000
--- a/mobile/app/pods/components/lights-tab/template.hbs
+++ /dev/null
@@ -1,42 +0,0 @@
-{{#paper-list}}
- {{#paper-item}}
- {{paper-icon "power-settings-new" class=dimmerOnClass}}
- Power
- {{paper-switch value=lightsOn onChange=(action (mut lightsOn)) disabled=(or trial playing) skipProxy=trial label=lightsOnTxt}}
- {{/paper-item}}
-
- {{#paper-item}}
- {{paper-icon "brightness-4" class=dimmerOnClass}}
- Brightness
- {{paper-slider class="flex" step=10 min=1 max=254 value=lightsBrightness onChange=(action (mut lightsBrightness)) disabled=brightnessControlDisabled}}
- {{/paper-item}}
-
- {{#paper-item class="color-row" }}
- {{paper-icon "color-lens" class=dimmerOnClass}}
- Color
- {{#paper-menu offset="0 -100" as |menu|}}
- {{#menu.trigger}}
- {{#paper-button iconButton=false}}
- {{paper-button raised=true class="color" disabled=(or trial playing)}}
- {{/paper-button}}
- {{/menu.trigger}}
- {{#menu.content class="color-content" width=8 as |content|}}
- {{#content.menu-item}}
- {{lights-tab/color-picker lightsData=lightsData activeLights=activeLights rgb=rgb}}
- {{/content.menu-item}}
- {{/menu.content}}
- {{/paper-menu}}
- {{/paper-item}}
-
- {{#paper-item}}
- {{paper-icon "flare" class=dimmerOnClass}}
- Strobe
- {{paper-switch value=strobeOn onChange=(action (mut strobeOn)) disabled=(or trial playing) skipProxy=trial label=strobeOnTxt}}
- {{/paper-item}}
-
- {{#paper-item}}
- {{paper-icon "color-lens" class=dimmerOnClass}} {{paper-icon "loop" id="loop-addition" class=dimmerOnClass}}
- Colorloop
- {{paper-switch value=colorLoopOn onChange=(action (mut colorLoopOn)) disabled=(or trial playing) skipProxy=trial label=colorloopOnTxt}}
- {{/paper-item}}
-{{/paper-list}}
\ No newline at end of file
diff --git a/mobile/app/pods/components/music-tab/add-soundcloud-sound-modal/component.js b/mobile/app/pods/components/music-tab/add-soundcloud-sound-modal/component.js
deleted file mode 100644
index 34cf66b..0000000
--- a/mobile/app/pods/components/music-tab/add-soundcloud-sound-modal/component.js
+++ /dev/null
@@ -1,46 +0,0 @@
-import Ember from 'ember';
-
-const {
- Component,
- observer,
- computed,
- isEmpty,
- isNone,
- run: { later },
- $
-} = Ember;
-
-export default Component.extend({
- url: null,
-
- onIsShowingModalChange: observer('isShowingModal', function(){
- if(this.get('isShowingModal')){
- this.set('url', null);
- later(this, function() {
- $('md-input-container input').focus();
- }, 500);
- }
-
- }),
-
- saveDisabled: computed('url', function(){
- return isNone(this.get('url')) || isEmpty(this.get('url').trim());
- }),
-
- didInsertElement: function() {
- $(document).keypress((event)=>{
- if(!this.get('saveDisabled') && event.which === 13) {
- this.send('add');
- }
- });
- },
-
- actions: {
- close () {
- this.sendAction();
- },
- add (){
- this.sendAction('action', this.get('url'));
- }
- }
-});
diff --git a/mobile/app/pods/components/music-tab/add-soundcloud-sound-modal/template.hbs b/mobile/app/pods/components/music-tab/add-soundcloud-sound-modal/template.hbs
deleted file mode 100644
index 61bcf77..0000000
--- a/mobile/app/pods/components/music-tab/add-soundcloud-sound-modal/template.hbs
+++ /dev/null
@@ -1,15 +0,0 @@
-{{#if isShowingModal}}
- {{#paper-dialog fullscreen=fullscreen onClose=(action "close") origin=dialogOrigin clickOutsideToClose=true}}
- {{#paper-dialog-content}}
- Enter a SoundCloud track or playlist/set
- URL
- (ex. https://soundcloud.com/mrsuicidesheep/tracks)
-
- {{paper-input label="SoundCloud URL" class="full-width" icon="search" value=url onChange=(action (mut url))}}
- {{/paper-dialog-content}}
-
- {{#paper-dialog-actions class="layout-row" }}
- {{paper-button onClick=(action "close") label="Close"}} {{paper-button class="pull-right" onClick=(action "add") disabled=saveDisabled primary=true label="Add Music"}}
- {{/paper-dialog-actions}}
- {{/paper-dialog}}
-{{/if}}
\ No newline at end of file
diff --git a/mobile/app/pods/components/music-tab/component.js b/mobile/app/pods/components/music-tab/component.js
deleted file mode 100644
index d3f9f99..0000000
--- a/mobile/app/pods/components/music-tab/component.js
+++ /dev/null
@@ -1,650 +0,0 @@
-import Ember from 'ember';
-import helperMixin from './mixins/helpers';
-import visualizerMixin from './mixins/visualizer';
-
-const {
- Component,
- observer,
- isEmpty,
- isNone,
- $,
- run: { later, next }
-} = Ember;
-
-export default Component.extend(helperMixin, visualizerMixin, {
- updatePageTitle: observer('playQueuePointer', function () {
- let title = 'Huegasm',
- playQueuePointer = this.get('playQueuePointer'),
- playQueue = this.get('playQueue');
-
- if (playQueuePointer !== -1) {
- let song = playQueue[playQueuePointer];
- if (song.title) {
- title = song.title;
-
- if (song.artist) {
- title += (' - ' + song.artist);
- }
- } else {
- title = song.fileName;
- }
-
- title += '- Huegasm';
- }
-
- document.title = title;
- }),
-
- changePlayerControl(name, value, saveBeatPrefs) {
- this.set(name, value);
-
- if (name === 'threshold') {
- this.get('kick').set({ threshold: value });
- }
-
- if (saveBeatPrefs && this.get('playQueuePointer') !== -1) {
- this.saveSongBeatPreferences();
- }
-
- this.get('storage').set('huegasm.' + name, value);
- },
-
- saveSongBeatPreferences() {
- let song = this.get('playQueue')[this.get('playQueuePointer')];
- if (song) {
- let title = isEmpty(song.artist) ? song.fileName : song.artist + '-' + song.title,
- songBeatPreferences = this.get('songBeatPreferences');
-
- songBeatPreferences[title] = { threshold: this.get('threshold') };
-
- this.set('usingBeatPreferences', true);
- this.get('storage').set('huegasm.songBeatPreferences', songBeatPreferences);
- }
- },
-
- loadSongBeatPreferences() {
- let song = this.get('playQueue')[this.get('playQueuePointer')],
- title = isEmpty(song.artist) ? song.fileName : song.artist + '-' + song.title,
- songBeatPreferences = this.get('songBeatPreferences'),
- preference = songBeatPreferences[title],
- oldBeatPrefCache = this.get('oldBeatPrefCache'),
- newOldBeatPrefCache = null;
-
- if (!isNone(preference)) { // load existing beat prefs
- newOldBeatPrefCache = { threshold: this.get('threshold') };
-
- this.changePlayerControl('threshold', preference.threshold);
- this.set('usingBeatPreferences', true);
- } else if (!isNone(oldBeatPrefCache)) { // revert to using beat prefs before the remembered song
- this.changePlayerControl('threshold', oldBeatPrefCache.threshold);
- this.set('usingBeatPreferences', false);
- }
-
- this.set('oldBeatPrefCache', newOldBeatPrefCache);
- },
-
- clearCurrentAudio(resetPointer) {
- let dancer = this.get('dancer');
-
- if (dancer.audio.pause) {
- dancer.pause();
- }
-
- if (resetPointer) {
- this.set('playQueuePointer', -1);
- }
-
- this.setProperties({
- timeElapsed: 0,
- timeTotal: 0,
- playing: false
- });
- },
-
- simulateKick(/*mag, ratioKickMag*/) {
- let activeLights = this.get('activeLights'),
- lightsData = this.get('lightsData'),
- color = null,
- transitiontime = this.get('flashingTransitions'),
- brightnessRange = this.get('brightnessRange'),
- stimulateLight = (light, brightness, hue) => {
- let options = { 'bri': brightness };
-
- if (transitiontime) {
- options['transitiontime'] = 0;
- } else {
- options['transitiontime'] = 1;
- }
-
- if (!isNone(hue)) {
- options.hue = hue;
- }
-
- if (lightsData[light].state.on === false) {
- options.on = true;
- }
-
- $.ajax(this.get('apiURL') + '/lights/' + light + '/state', {
- data: JSON.stringify(options),
- contentType: 'application/json',
- type: 'PUT'
- });
- },
- timeToBriOff = 100;
-
- if (activeLights.length > 0) {
- let lastLightBopIndex = this.get('lastLightBopIndex'),
- lightBopIndex,
- light;
-
- lightBopIndex = Math.floor(Math.random() * activeLights.length);
-
- // let's try not to select the same light twice in a row
- if (activeLights.length > 1) {
- while (lightBopIndex === lastLightBopIndex) {
- lightBopIndex = Math.floor(Math.random() * activeLights.length);
- }
- }
-
- light = activeLights[lightBopIndex];
- this.set('lastLightBopIndex', lightBopIndex);
-
- if (!this.get('colorloopMode')) {
- let hueRange = this.get('hueRange');
-
- color = Math.floor(Math.random() * (hueRange[1] - hueRange[0] + 1) + hueRange[0]);
- }
-
- if (transitiontime) {
- timeToBriOff = 80;
- }
-
- stimulateLight(light, brightnessRange[1]);
- later(this, stimulateLight, light, brightnessRange[0], color, timeToBriOff);
- }
-
- this.set('paused', true);
- later(this, function () {
- this.set('paused', false);
- }, 200);
-
- //work the music beat area - simulate the speaker vibration by running a CSS animation on it
- $('#beat-speaker-center-outer').velocity({ blur: 3 }, 100).velocity({ blur: 0 }, 100);
- $('#beat-speaker-center-inner').velocity({ scale: 1.05 }, 100).velocity({ scale: 1 }, 100);
- },
-
- init() {
- this._super(...arguments);
-
- window.requestAnimationFrame = window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || window.msRequestAnimationFrame;
- window.cancelAnimationFrame = window.cancelAnimationFrame || window.webkitCancelAnimationFrame || window.mozCancelAnimationFrame || window.msCancelAnimationFrame;
- navigator.getUserMedia = navigator.getUserMedia || navigator.webkitGetUserMedia || navigator.mozGetUserMedia || navigator.msGetUserMedia;
-
- let dancer = new Dancer(),
- storage = this.get('storage'),
- kick = dancer.createKick({
- threshold: this.get('threshold'),
- onKick: (mag, ratioKickMag) => {
- if (this.get('paused') === false) {
- this.simulateKick(mag, ratioKickMag);
- }
- }
- });
-
- kick.on();
-
- this.setProperties({
- dancer: dancer,
- kick: kick
- });
-
- ['shuffle', 'repeat', 'threshold', 'playerBottomDisplayed', 'audioMode', 'songBeatPreferences', 'firstVisit', 'currentVisName', 'playQueue', 'playQueuePointer', 'flashingTransitions', 'colorloopMode', 'hueRange', 'brightnessRange'].forEach((item) => {
- if (!isNone(storage.get('huegasm.' + item))) {
- let itemVal = storage.get('huegasm.' + item);
-
- if (isNone(this.actions[item + 'Changed'])) {
- this.set(item, itemVal);
- } else {
- this.send(item + 'Changed', itemVal);
- }
- }
- });
-
- SC.initialize({
- client_id: this.get('SC_CLIENT_ID')
- });
-
- this.set('oldPlayQueueLength', this.get('playQueue.length'));
-
- document.addEventListener('stop', () => {
- if (this.get('playing')) {
- this.send('play');
- }
- }, false);
- },
-
- didInsertElement() {
- this._super();
-
- let self = this;
-
- // perfect-scrollbar
- Ps.initialize(document.getElementById('play-list-area'), {
- swipePropagation: false
- });
-
- // file input code
- $('#file-input').on('change', function () {
- let files = this.files;
- self.send('handleNewFiles', files);
- this.value = null; // reset in case upload the second file again
- });
-
- $(document).on('click', '.alert', (event) => {
- $(event.target).addClass('removed');
- });
-
- $(document).keypress((event) => {
- if (event.which === 32 && event.target.type !== 'text') {
- this.send('play');
- }
- });
-
- // demo tracks
- if (this.get('firstVisit')) {
- this.send('handleNewSoundCloudURL', 'https://soundcloud.com/mrsuicidesheep/candyland-speechless-feat-rkcb');
- this.send('handleNewSoundCloudURL', 'https://soundcloud.com/dillistone/dillistone-lili-n-rude');
- this.send('handleNewSoundCloudURL', 'https://soundcloud.com/mrsuicidesheep/vallis-alps-young-feki-remix');
- this.send('handleNewSoundCloudURL', 'https://soundcloud.com/mrsuicidesheep/andrew-luce-when-to-love-you-feat-chelsea-cutler');
- this.send('handleNewSoundCloudURL', 'https://soundcloud.com/mrsuicidesheep/ahh-ooh-carefree-with-me');
- this.send('handleNewSoundCloudURL', 'https://soundcloud.com/mrsuicidesheep/crywolf-slow-burn');
- this.send('handleNewSoundCloudURL', 'https://soundcloud.com/mrsuicidesheep/clozee-red-forest');
- this.send('handleNewSoundCloudURL', 'https://soundcloud.com/mrsuicidesheep/elo-method-subranger-solace');
- this.send('handleNewSoundCloudURL', 'https://soundcloud.com/mrsuicidesheep/90-pounds-of-pete-waited-too-long-feat-devon-baldwin');
- this.send('handleNewSoundCloudURL', 'https://soundcloud.com/mrsuicidesheep/draper-eyes-open');
- this.send('handleNewSoundCloudURL', 'https://soundcloud.com/itspapaya/sunny');
- this.send('handleNewSoundCloudURL', 'https://soundcloud.com/stonesthrow/nxworries-anderson-paak-knxwledge-suede');
-
- this.get('storage').set('huegasm.firstVisit', false);
-
- this.sendAction();
- }
-
- if (!this.get('playerBottomDisplayed')) {
- $('#player-bottom').hide();
- }
- },
-
- actions: {
- setVisName(name) {
- this.set('currentVisName', name);
- },
- gotoSCURL(URL) {
- // need to pause the music since soundcloud is going to start playing this song anyways
- if (this.get('playing')) {
- this.send('play');
- }
-
- this.send('gotoURL', URL);
- },
- gotoURL(URL) {
- window.open(URL, '_blank');
- },
- handleNewSoundCloudURL(URL) {
- if (URL) {
- SC.resolve(URL).then((resultObj) => {
- let processResult = (result) => {
- if (result.kind === 'user') {
- this.get('notify').alert({ html: this.get('scUserNotSupportedHtml') });
- } else if (result.kind === 'track') {
- if (result.streamable === true) {
- let picture = null;
-
- if (result.artwork_url) {
- picture = result.artwork_url.replace('large', 't67x67');
- } else if (result.user.avatar_url) {
- picture = result.user.avatar_url;
- }
-
- $.get(picture)
- .done(() => {
- this.get('playQueue').pushObject({ url: result.stream_url + '?client_id=' + this.get('SC_CLIENT_ID'), fileName: result.title + ' - ' + result.user.username, artist: result.user.username, scUrl: result.permalink_url, title: result.title, picture: picture });
- }).fail(() => { // no picture
- this.get('playQueue').pushObject({ url: result.stream_url + '?client_id=' + this.get('SC_CLIENT_ID'), fileName: result.title + ' - ' + result.user.username, artist: result.user.username, scUrl: result.permalink_url, title: result.title });
- });
- } else {
- failedSongs.push(result.title);
- }
- } else if (result.kind === 'playlist') {
- if (result.streamable === true) {
- result.tracks.forEach(processResult);
- } else {
- failedSongs.push(result.title);
- }
- }
- },
- failedSongs = [];
-
- if (resultObj instanceof Array) {
- resultObj.forEach(processResult);
- } else {
- processResult(resultObj);
- }
-
- if (failedSongs.length > 0) {
- this.get('notify').alert({ html: this.get('notStreamableHtml')(failedSongs) });
- }
-
- if (this.get('playQueuePointer') === -1) {
- if (this.get('firstVisit')) {
- this.send('goToSong', 0);
- } else {
- this.send('next');
- }
- }
- }, () => {
- this.get('notify').alert({ html: this.get('urlNotFoundHtml')(URL) });
- });
- }
-
- this.set('isShowingAddSoundCloudModal', false);
- },
- toggleIsShowingAddSoundCloudModal() {
- this.toggleProperty('isShowingAddSoundCloudModal');
- },
- slideTogglePlayerBottom() {
- let elem = this.$('#player-bottom');
-
- elem.velocity(elem.is(':visible') ? 'slideUp' : 'slideDown', { duration: 300 });
- this.changePlayerControl('playerBottomDisplayed', !this.get('playerBottomDisplayed'));
- },
- goToSong(index, playSong, scrollToSong) {
- let dancer = this.get('dancer'), playQueue = this.get('playQueue');
-
- if (dancer.audio) {
- this.clearCurrentAudio(true);
- }
-
- if (!isNone(playQueue[index])) {
- let audio = new Audio();
- audio.src = this.get('playQueue')[index].url;
-
- audio.crossOrigin = "anonymous";
- audio.oncanplay = () => {
- this.set('timeTotal', Math.floor(audio.duration));
- this.set('soundCloudFuckUps', 0);
- };
- audio.onerror = (event) => {
- let playQueuePointer = this.get('playQueuePointer'),
- song = this.get('playQueue')[playQueuePointer];
-
- if (this.get('soundCloudFuckUps') >= this.get('maxSoundCloudFuckUps')) {
- this.get('notify').alert({ html: this.get('tooManySoundCloudFuckUps') });
- this.send('play');
- this.set('soundCloudFuckUps', 0);
- } else {
- if (song.local) {
- this.send('removeAudio', playQueuePointer);
- } else {
- this.send('next', true);
- }
-
- if (event.target.error.code === 2) {
- this.get('notify').alert({ html: this.get('failedToDecodeFileHtml')(song.fileName) });
- } else {
- this.get('notify').alert({ html: this.get('failedToPlayFileHtml')(song.fileName) });
- }
-
- this.set('usingBeatPreferences', false);
- this.incrementProperty('soundCloudFuckUps');
- }
- };
- audio.ontimeupdate = () => {
- this.set('timeElapsed', Math.floor(audio.currentTime));
- };
- audio.onended = () => {
- this.send('next');
- };
-
- dancer.load(audio, 1);
-
- this.set('playQueuePointer', index);
-
- this.loadSongBeatPreferences();
-
- if (playSong) {
- this.send('play');
- }
-
- if (scrollToSong) {
- next(this, () => {
- $('.track' + index).velocity('scroll', { container: $('#play-list-area'), duration: 200 });
- });
- }
- }
- },
- removeAudio(index) {
- this.get('playQueue').removeAt(index);
-
- if (index === this.get('playQueuePointer')) {
- this.send('goToSong', index, true, true);
- }
- },
- playerAreaPlay() {
- if (isEmpty($('#player-controls:hover')) && this.get('playQueuePointer') !== -1) {
- this.send('play');
-
- $('#play-notification').velocity({ opacity: 1, scale: 1 }, 0).velocity({ opacity: 0, scale: 3 }, 500);
- }
- },
- play(replayPause) {
- let dancer = this.get('dancer'),
- playQueuePointer = this.get('playQueuePointer'),
- playing = this.get('playing'),
- lightsData = this.get('lightsData');
-
- if (playQueuePointer !== -1) {
- if (playing) {
- dancer.pause();
-
- let preMusicLightsDataCache = this.get('preMusicLightsDataCache'),
- updateLight = (lightIndex) => {
- $.ajax(this.get('apiURL') + '/lights/' + lightIndex + '/state', {
- data: JSON.stringify({
- 'on': preMusicLightsDataCache[lightIndex].state.on,
- 'hue': preMusicLightsDataCache[lightIndex].state.hue,
- 'bri': preMusicLightsDataCache[lightIndex].state.bri
- }),
- contentType: 'application/json',
- type: 'PUT'
- });
- };
-
- for (let key in lightsData) {
- if (lightsData.hasOwnProperty(key)) {
- later(this, updateLight, key, 1000);
- }
- }
-
- if (!replayPause) {
- this.set('timeElapsed', Math.floor(dancer.getTime()));
- }
- } else {
- let timeTotal = this.get('timeTotal');
-
- // replay song
- if (this.get('timeElapsed') === timeTotal && timeTotal !== 0) {
- this.send('next', true);
- return;
- }
-
- $(window).trigger('resize'); // workaround to redraw the canvas for the vitualizer
-
- this.set('preMusicLightsDataCache', lightsData);
- dancer.play();
- }
-
- this.set('pauseLightUpdates', !playing);
- this.onColorloopModeChange();
- this.toggleProperty('playing');
- }
- },
- next(repeatAll) {
- let playQueuePointer = this.get('playQueuePointer'),
- playQueue = this.get('playQueue'),
- nextSong = (playQueuePointer + 1),
- repeat = this.get('repeat'),
- shuffle = this.get('shuffle');
-
- if (repeat === 2) { // repeating one song takes precedence over shuffling
- if (playQueuePointer === -1 && playQueue.length > 0) {
- nextSong = 0;
- } else {
- nextSong = playQueuePointer;
- }
- } else if (shuffle) { // next shuffle song
- let shufflePlayed = this.get('shufflePlayed');
-
- // played all the song in shuffle mode
- if (shufflePlayed.length === playQueue.length) {
- shufflePlayed.clear();
- this.send('play', true);
- return;
- }
-
- // we're going to assume that the song URL is the id
- do {
- nextSong = Math.floor(Math.random() * playQueue.length);
- } while (shufflePlayed.includes(playQueue[nextSong].url));
-
- shufflePlayed.pushObject(playQueue[nextSong].url);
- } else if (nextSong > playQueue.length - 1) {
- if (repeat === 1 || repeatAll) {
- nextSong = nextSong % playQueue.length;
- } else {
- this.send('play', true);
- return;
- }
- }
-
- this.send('goToSong', nextSong, true, true);
- },
- previous() {
- if (this.get('timeElapsed') > 5) {
- this.send('seekChanged', 0);
- } else {
- let nextSong = this.get('playQueuePointer'),
- playQueue = this.get('playQueue');
-
- if (this.get('shuffle') && !isNone(playQueue[nextSong])) { // go to the previously shuffled song
- let shufflePlayed = this.get('shufflePlayed'),
- shuffledSongIndx = this.get('shufflePlayed').indexOf(playQueue[nextSong].url),
- i = 0;
-
- if (shufflePlayed.length > 0 && shuffledSongIndx !== -1) { // only if there was one
- nextSong = shuffledSongIndx - 1;
-
- if (nextSong < 0) {
- nextSong = shufflePlayed.length - 1;
- }
-
- playQueue.some(function (item) { // try to find the previous song id
- if (item.url === shufflePlayed[nextSong]) {
- nextSong = i;
- return true;
- }
- i++;
-
- return false;
- });
- }
- } else {
- nextSong--;
-
- if (nextSong < 0) {
- nextSong = playQueue.length - 1;
- }
- }
-
- this.send('goToSong', nextSong, true, true);
- }
- },
- seekChanged(position) {
- let dancer = this.get('dancer');
-
- if (dancer.audio) {
- dancer.audio.currentTime = Math.floor(this.get('timeTotal') * position / 100);
- }
- },
- addLocalAudio: function () {
- $('#file-input').click();
- },
- shuffleChanged(value) {
- this.changePlayerControl('shuffle', isNone(value) ? !this.get('shuffle') : value);
- },
- repeatChanged(value) {
- this.changePlayerControl('repeat', isNone(value) ? (this.get('repeat') + 1) % 3 : value);
- },
- playerBottomDisplayedChanged(value) {
- this.changePlayerControl('playerBottomDisplayed', value);
- },
- thresholdChanged(value) {
- this.changePlayerControl('threshold', value, true);
- },
- brightnessRangeChanged(value) {
- this.changePlayerControl('brightnessRange', value);
- },
- hueRangeChanged(value) {
- this.changePlayerControl('hueRange', value);
- },
- playQueuePointerChanged(value) {
- this.send('goToSong', value, false, true);
- },
- clickSpeaker() {
- this.simulateKick(1);
- },
- handleNewFiles(files) {
- let self = this,
- playQueue = this.get('playQueue'),
- updatePlayQueue = function () {
- let tags = ID3.getAllTags("local"),
- picture = null;
-
- if (tags.picture) {
- let base64String = "";
- for (let i = 0; i < tags.picture.data.length; i++) {
- base64String += String.fromCharCode(tags.picture.data[i]);
- }
-
- picture = "data:" + tags.picture.format + ";base64," + window.btoa(base64String);
- }
-
- playQueue.pushObject({
- fileName: this.name.replace(/\.[^/.]+$/, ""),
- url: URL.createObjectURL(this),
- artist: tags.artist,
- title: tags.title,
- picture: picture,
- local: true
- });
-
- ID3.clearAll();
-
- if (self.get('playQueuePointer') === -1) {
- self.send('next');
- }
- };
-
- for (let key in files) {
- if (files.hasOwnProperty(key)) {
- let file = files[key];
-
- ID3.loadTags("local", updatePlayQueue.bind(file), {
- dataReader: new FileAPIReader(file),
- tags: ['title', 'artist', 'album', 'track', 'picture']
- });
- }
- }
- }
- }
-});
diff --git a/mobile/app/pods/components/music-tab/mixins/helpers.js b/mobile/app/pods/components/music-tab/mixins/helpers.js
deleted file mode 100644
index 90ad01e..0000000
--- a/mobile/app/pods/components/music-tab/mixins/helpers.js
+++ /dev/null
@@ -1,325 +0,0 @@
-import Ember from 'ember';
-
-const {
- Mixin,
- observer,
- computed,
- run,
- isNone,
- inject,
- $,
- A
-} = Ember;
-
-export default Mixin.create({
- classNames: ['col-xs-12'],
- classNameBindings: ['active::hidden'],
- elementId: 'music-tab',
-
- dancer: null,
-
- notify: inject.service('notify'),
-
- beatOptions: {
- threshold: {
- range: { min: 0, max: 0.5 },
- step: 0.01,
- defaultValue: 0.3,
- pips: {
- mode: 'values',
- values: [0, 0.25, 0.5],
- density: 10,
- format: {
- to: function (value) {
- if (value === 0) {
- value = 'High';
- } else if (value === 0.25) {
- value = '';
- } else {
- value = 'Low';
- }
-
- return value;
- },
- from: function (value) { return value; }
- }
- }
- },
- hueRange: {
- range: { min: 0, max: 65535 },
- step: 1,
- defaultValue: 0.3,
- pips: {
- mode: 'values',
- values: [0, 25500, 46920, 65535],
- density: 10,
- format: {
- to: function (value) {
- if (value === 0 || value === 65535) {
- value = 'Red';
- } else if (value === 25500) {
- value = 'Green';
- } else {
- value = 'Blue';
- }
-
- return value;
- },
- from: function (value) { return value; }
- }
- }
- },
- brightnessRange: {
- range: { min: 1, max: 254 },
- step: 1,
- defaultValue: 0,
- pips: {
- mode: 'values',
- values: [1, 63, 127, 190, 254],
- density: 10,
- format: {
- to: function (value) {
- if (value === 63) {
- value = 25;
- } else if (value === 127) {
- value = 50;
- } else if (value === 190) {
- value = 75;
- } else if (value === 254) {
- value = 100;
- }
-
- return value;
- },
- from: function (value) { return value; }
- }
- }
- }
- },
-
- threshold: 0.3,
- hueRange: [0, 65535],
- brightnessRange: [1, 254],
- oldThreshold: null,
-
- playQueuePointer: -1,
- playQueue: A(),
- timeElapsed: 0,
- timeTotal: 0,
- lastLightBopIndex: 0,
-
- playerBottomDisplayed: true,
- dragging: false,
- draggingOverPlayListArea: false,
- isShowingAddSoundCloudModal: false,
-
- colorloopMode: false,
- flashingTransitions: false,
-
- // 0 - no repeat, 1 - repeat all, 2 - repeat one
- repeat: 0,
- shuffle: false,
- volume: 100,
- // beat detection related pausing
- paused: false,
- // audio: playing or paused
- playing: false,
- songBeatPreferences: {},
- usingBeatPreferences: false,
- oldBeatPrefCache: null,
- storage: null,
- firstVisit: true,
-
- soundCloudFuckUps: 0,
- maxSoundCloudFuckUps: 3,
-
- // used to insure that we don't replay the same thing multiple times in shuffle mode
- shufflePlayed: [],
-
- // noUiSlider connection specification
- filledConnect: [true, false],
- hueRangeConnect: [false, true, false],
-
- SC_CLIENT_ID: 'aeec0034f58ecd85c2bd1deaecc41594',
- scUserNotSupportedHtml: 'SoundCloud user URLs are not supported.
',
- tooManySoundCloudFuckUps: 'The SoundCloud API is not seving the audio properly. More details
HERE .
',
- notStreamableHtml(fileNames) {
- let html = 'The following file(s) could not be added because they are not allowed to be streamed: ' + fileNames.toString().replace(/,/g, ' ') + '
';
-
- return html;
- },
- urlNotFoundHtml(url) {
- return 'The URL (' + url + ') could not be resolved.
';
- },
- failedToPlayFileHtml(fileName) {
- return 'Failed to play file (' + fileName + ').
';
- },
- failedToDecodeFileHtml(fileName) {
- return 'Failed to decode file (' + fileName + ').
';
- },
-
- scUrl: computed('playQueuePointer', 'playQueue.[]', function () {
- let rtn = null,
- currentSong = this.get('playQueue')[this.get('playQueuePointer')];
-
- if (currentSong && currentSong.scUrl) {
- rtn = currentSong.scUrl;
- }
-
- return rtn;
- }),
-
- playQueueEmpty: computed.empty('playQueue'),
- playQueueNotEmpty: computed.notEmpty('playQueue'),
- playQueueMultiple: computed('playQueue.[]', function () {
- return this.get('playQueue').length > 1;
- }),
-
- seekPosition: computed('timeElapsed', 'timeTotal', function () {
- let timeTotal = this.get('timeTotal'),
- timeElapsed = this.get('timeElapsed');
-
- if (timeTotal === 0) {
- return 0;
- }
-
- return timeElapsed / timeTotal * 100;
- }),
-
- largeArtworkPic: computed('playQueuePointer', 'currentVisName', function () {
- let pic = '',
- currentVisName = this.get('currentVisName'),
- playQueuePointer = this.get('playQueuePointer'),
- playQueue = this.get('playQueue');
-
- if (playQueuePointer !== -1 && currentVisName === 'None') {
- let song = playQueue[playQueuePointer];
- if (!isNone(song.picture)) {
- pic = song.picture;
-
- if (song.scUrl) {
- pic = pic.replace('67x67', '500x500');
- }
- }
- }
-
- return pic;
- }),
-
- repeatIcon: computed('repeat', function () {
- if (this.get('repeat') === 2) {
- return 'repeat-one';
- }
-
- return 'repeat';
- }),
-
- playingIcon: computed('playing', function () {
- if (this.get('playing')) {
- return 'pause';
- } else if (this.get('timeElapsed') === this.get('timeTotal') && this.get('timeTotal') !== 0) {
- return 'replay';
- } else {
- return 'play-arrow';
- }
- }),
-
- playerAreaClickIcon: computed('playing', function () {
- if (this.get('playing')) {
- return 'play-arrow';
- } else {
- return 'pause';
- }
- }),
-
- playListAreaClass: computed('dragging', 'draggingOverPlayListArea', 'dimmerOn', function () {
- let classes = 'pointer';
-
- if (this.get('dragging')) {
- classes += ' drag-here-highlight';
- }
-
- if (this.get('draggingOverPlayListArea')) {
- classes += ' dragging-over';
- }
-
- if (this.get('dimmerOn')) {
- classes += ' dimmerOn';
- }
-
- return classes;
- }),
-
- dimmerOnClass: computed('dimmerOn', function () {
- return this.get('dimmerOn') ? 'dimmerOn' : null;
- }),
-
- repeatClass: computed('repeat', function () {
- return this.get('repeat') !== 0 ? 'player-control-icon active' : 'player-control-icon';
- }),
-
- shuffleClass: computed('shuffle', function () {
- return this.get('shuffle') ? 'player-control-icon active' : 'player-control-icon';
- }),
-
- beatDetectionAreaArrowIcon: computed('playerBottomDisplayed', function () {
- if (!this.get('playerBottomDisplayed')) {
- return 'keyboard-arrow-down';
- } else {
- return 'keyboard-arrow-up';
- }
- }),
-
- timeElapsedTxt: computed('timeElapsed', function () {
- return this.formatTime(this.get('timeElapsed'));
- }),
-
- timeTotalTxt: computed('timeTotal', function () {
- return this.formatTime(this.get('timeTotal'));
- }),
-
- onPlayQueueChange: observer('playQueue.length', function () {
- let playQueueLength = this.get('playQueue.length');
-
- if (playQueueLength > this.get('oldPlayQueueLength')) {
- run.once(this, () => {
- run.next(this, function () {
- $(`.track${playQueueLength - 1}`).velocity('scroll', { container: $('#play-list-area'), duration: 200 });
- Ps.update(document.getElementById('play-list-area'));
- });
- });
- } else {
- run.once(this, () => {
- run.next(this, function () {
- Ps.update(document.getElementById('play-list-area'));
- });
- });
- }
-
- this.set('oldPlayQueueLength', playQueueLength);
- }),
-
- onColorloopModeChange: observer('colorloopMode', 'playing', function () {
- this.set('colorLoopOn', this.get('playing') && this.get('colorloopMode'));
- }),
-
- onOptionChange: observer('flashingTransitions', 'playQueue.[]', 'playQueuePointer', 'colorloopMode', function (self, option) {
- option = option.replace('.[]', '');
- let value = this.get(option);
-
- // can't really save local music
- if (option === 'playQueue') {
- value = value.filter((song) => {
- return !song.url.startsWith('blob:');
- });
- }
-
- this.get('storage').set('huegasm.' + option, value);
- }),
-
- formatTime(time) {
- return this.pad(Math.floor(time / 60), 2) + ':' + this.pad(time % 60, 2);
- },
-
- pad(num, size) { return ('000000000' + num).substr(-size); }
-});
diff --git a/mobile/app/pods/components/music-tab/mixins/visualizer.js b/mobile/app/pods/components/music-tab/mixins/visualizer.js
deleted file mode 100644
index 17dcfe2..0000000
--- a/mobile/app/pods/components/music-tab/mixins/visualizer.js
+++ /dev/null
@@ -1,94 +0,0 @@
-import Ember from 'ember';
-
-const {
- Mixin,
- observer,
- $
-} = Ember;
-
-export default Mixin.create({
- currentVisName: 'None',
-
- visNames: ['None', 'Bars', 'Wave'],
-
- onCurrentVisNameChange: observer('currentVisName', function () {
- let currentVisName = this.get('currentVisName');
-
- if(currentVisName === 'None'){
- let canvasEl = $('#visualization')[0],
- ctx = canvasEl.getContext('2d');
-
- ctx.clearRect(0, 0, canvasEl.width, canvasEl.height);
- }
-
- this.get('storage').set('huegasm.currentVisName', currentVisName);
- }),
-
- didInsertElement(){
- let dancer = this.get('dancer'),
- canvas = $('#visualization')[0],
- playerArea = $('#player-area'),
- ctx = canvas.getContext('2d'),
- spacing = 2,
- h = playerArea.height(), w;
-
- canvas.height = h;
-
- // must be done to preserver resolution so that things don't appear blurry
- // note that the height is set to 400px via css so it doesn't need to be recalculated
- let syncCanvasHeight = ()=>{
- w = playerArea.width();
- canvas.width = w;
- };
-
- syncCanvasHeight();
-
- $(window).on('resize', syncCanvasHeight);
-
- dancer.bind('update', () => {
- let currentVisName = this.get('currentVisName'),
- gradient = ctx.createLinearGradient(0, 0, 0, h),
- pageHidden = document.hidden || document.msHidden || document.webkitHidden || document.mozHidden;
-
- // dont do anything if the page is hidden or no visualization
- if(currentVisName === 'None' || pageHidden || !this.get('active')){
- return;
- }
-
- ctx.clearRect(0, 0, w, h);
-
- if (currentVisName === 'Wave') {
- let width = 3,
- count = 1024;
-
- gradient.addColorStop(0.6, 'white');
- gradient.addColorStop(0, '#0036FA');
-
- ctx.lineWidth = 1;
- ctx.strokeStyle = gradient;
- let waveform = dancer.getWaveform();
-
- ctx.beginPath();
- ctx.moveTo(0, h / 2);
- for (let i = 0, l = waveform.length; i < l && i < count; i++) {
- ctx.lineTo(i * ( spacing + width ), ( h / 2 ) + waveform[i] * ( h / 2 ));
- }
- ctx.stroke();
- ctx.closePath();
- } else if (currentVisName === 'Bars') {
- let width = 4,
- count = 128;
-
- gradient.addColorStop(1, '#0f0');
- gradient.addColorStop(0.6, '#ff0');
- gradient.addColorStop(0.2, '#F12B24');
-
- ctx.fillStyle = gradient;
- let spectrum = dancer.getSpectrum();
- for (let i = 0, l = spectrum.length; i < l && i < count; i++) {
- ctx.fillRect(i * ( spacing + width ), h, width, -spectrum[i] * h - 60);
- }
- }
- });
- }
-});
diff --git a/mobile/app/pods/components/music-tab/template.hbs b/mobile/app/pods/components/music-tab/template.hbs
deleted file mode 100644
index 326769b..0000000
--- a/mobile/app/pods/components/music-tab/template.hbs
+++ /dev/null
@@ -1,165 +0,0 @@
-
-
-
-
-
-
-
-
- {{paper-icon playerAreaClickIcon id="play-notification"}}
-
-
- {{range-slider start=seekPosition min=0 max=100 connect=filledConnect id="seek-slider" on-change="seekChanged"}}
-
- {{#if playQueueNotEmpty}}
-
{{paper-icon "skip-previous" class="player-control-icon"}} {{/if}}
{{paper-icon playingIcon class="player-control-icon"}} {{#if playQueueMultiple}}
{{paper-icon "skip-next" action="" class="player-control-icon"}} {{/if}}
-
-
{{timeElapsedTxt}} / {{timeTotalTxt}}
-
- {{#paper-menu as |menu|}}
- {{#menu.trigger}}
- {{#paper-button iconButton=true}}
- {{paper-icon "remove-red-eye" class="player-control-icon"}}
- {{/paper-button}}
- {{/menu.trigger}}
- {{#menu.content width=2 as |content|}}
- {{#each visNames as |name|}}
- {{#content.menu-item onClick=(action "setVisName" name)}}
- {{name}}
-
- {{#if (eq currentVisName name)}}
- {{paper-icon "check" classNames=dimmerOnClass}}
- {{/if}}
- {{/content.menu-item}}
- {{/each}}
- {{/menu.content}}
- {{/paper-menu}}
-
- {{#if scUrl}}
-
-
-
-
- {{/if}}
-
-
-
-
-
-
-
- {{#paper-menu as |menu|}}
- {{#menu.trigger}}
- {{#paper-button iconButton=false}}
- {{paper-icon "playlist add" class="player-control-icon"}} Add new music
- {{/paper-button}}
- {{/menu.trigger}}
- {{#menu.content width=3 as |content|}}
- {{#content.menu-item onClick="addLocalAudio"}}
- {{paper-icon "attachment" class=shuffleClass}} Local file
- {{/content.menu-item}}
- {{#content.menu-item onClick="toggleIsShowingAddSoundCloudModal"}}
- {{paper-icon "cloud" class=shuffleClass}} SoundCloud
- {{/content.menu-item}}
- {{/menu.content}}
- {{/paper-menu}}
-
- {{paper-icon "shuffle" class=shuffleClass}}
- {{paper-icon repeatIcon class=repeatClass}}
-
-
-
- {{#if playQueueEmpty}}
-
- Add your music files here
-
- {{paper-icon "library-music" class=dimmerOnClass}}
- {{/if}}
-
- {{#each playQueue as |item index|}}
-
- {{#if item.picture}}
-
- {{else}}
-
- {{/if}}
-
-
- {{#if item.title}}
-
{{item.title}}
-
- {{#if item.artistUrl}}
-
{{item.artist}}
- {{else}}
- {{item.artist}}
- {{/if}}
-
- {{else}}
- {{item.fileName}}
- {{/if}}
-
-
-
{{paper-icon "close" classNames="close"}}
-
- {{/each}}
-
-
-
-
-
-
-
- {{paper-icon beatDetectionAreaArrowIcon id="beat-detection-area-arrow-icon"}}
-
-
-
-
-
- {{#if usingBeatPreferences}}
-
- {{paper-icon "star" class=dimmerOnClass}}
-
- {{/if}}
-
-
-
-
- Hue Range
-
-
- {{range-slider start=hueRange orientation="vertical" step=beatOptions.hueRange.step range=beatOptions.hueRange.range connect=hueRangeConnect on-change="hueRangeChanged" pips=beatOptions.hueRange.pips}}
-
-
-
-
- Brightness Range
-
-
- {{range-slider start=brightnessRange orientation="vertical" step=beatOptions.brightnessRange.step range=beatOptions.brightnessRange.range on-change="brightnessRangeChanged" pips=beatOptions.brightnessRange.pips}}
-
-
-
-
- Sensitivity
-
-
- {{range-slider start=threshold orientation="vertical" step=beatOptions.threshold.step range=beatOptions.threshold.range on-change="thresholdChanged" pips=beatOptions.threshold.pips}}
-
-
-
-
-
- {{paper-checkbox value=flashingTransitions onChange=(action (mut flashingTransitions)) label="Flashing Transitions"}}
-
-
-
- {{paper-checkbox value=colorloopMode onChange=(action (mut colorloopMode)) label="Colorloop"}}
-
-
-
-{{music-tab/add-soundcloud-sound-modal action="handleNewSoundCloudURL" isShowingModal=isShowingAddSoundCloudModal}}
\ No newline at end of file
diff --git a/mobile/app/resolver.js b/mobile/app/resolver.js
deleted file mode 100644
index 2fb563d..0000000
--- a/mobile/app/resolver.js
+++ /dev/null
@@ -1,3 +0,0 @@
-import Resolver from 'ember-resolver';
-
-export default Resolver;
diff --git a/mobile/app/router.js b/mobile/app/router.js
deleted file mode 100644
index cdc2578..0000000
--- a/mobile/app/router.js
+++ /dev/null
@@ -1,12 +0,0 @@
-import Ember from 'ember';
-import config from './config/environment';
-
-const Router = Ember.Router.extend({
- location: config.locationType,
- rootURL: config.rootURL
-});
-
-Router.map(function() {
-});
-
-export default Router;
diff --git a/mobile/app/styles/app.scss b/mobile/app/styles/app.scss
deleted file mode 100644
index 3db559a..0000000
--- a/mobile/app/styles/app.scss
+++ /dev/null
@@ -1,49 +0,0 @@
-@import 'huegasm-variables';
-
-@import 'bootstrap'; // used to take out bootstrap scss modules that we don't need
-@import 'paper';
-
-@import 'bridge-finder';
-@import 'common';
-@import 'dimmer';
-@import 'introjs';
-@import 'hue-controls';
-@import 'light-group';
-@import 'music-tab';
-@import 'noui-slider';
-
-[data-ember-action] {
- cursor: pointer;
- text-decoration: none;
-}
-
--webkit-tap-highlight-color {
- rgba: (0, 0, 0, 0);
-}
-
-body, button {
- font-family: 'Raleway', sans-serif;
-}
-
-.full-width {
- width: 100%;
-}
-
-md-dialog {
- p {
- word-break: break-word;
- }
-}
-
-.alert {
- margin-bottom: 0;
- border: none;
-}
-
-button.md-warn {
- background: $secondaryThemeColor;
-}
-
-.ps-scrollbar-y-rail {
- opacity: 1 !important;
-}
diff --git a/mobile/app/styles/bootstrap.scss b/mobile/app/styles/bootstrap.scss
deleted file mode 100644
index 18c9cc3..0000000
--- a/mobile/app/styles/bootstrap.scss
+++ /dev/null
@@ -1,56 +0,0 @@
-/*!
- * Bootstrap v3.3.7 (http://getbootstrap.com)
- * Copyright 2011-2016 Twitter, Inc.
- * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
- */
-
-// Core variables and mixins
-@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/variables";
-@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/mixins";
-
-// Reset and dependencies
-@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/normalize";
-//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/print";
-@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/glyphicons";
-
-// Core CSS
-@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/scaffolding";
-@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/type";
-//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/code";
-@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/grid";
-//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/tables";
-@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/forms";
-@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/buttons";
-
-// Components
-//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/component-animations";
-@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/dropdowns";
-//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/button-groups";
-@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/input-groups";
-//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/navs";
-//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/navbar";
-//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/breadcrumbs";
-//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/pagination";
-//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/pager";
-//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/labels";
-//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/badges";
-//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/jumbotron";
-//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/thumbnails";
-@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/alerts";
-//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/progress-bars";
-//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/media";
-//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/list-group";
-//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/panels";
-//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/responsive-embed";
-//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/wells";
-//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/close";
-
-// Components w/ JavaScript
-//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/modals";
-//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/tooltip";
-@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/popovers";
-//@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/carousel";
-
-// Utility classes
-@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/utilities";
-@import "bower_components/bootstrap-sass/assets/stylesheets/bootstrap/responsive-utilities";
diff --git a/mobile/app/styles/bridge-finder.scss b/mobile/app/styles/bridge-finder.scss
deleted file mode 100644
index 73f507a..0000000
--- a/mobile/app/styles/bridge-finder.scss
+++ /dev/null
@@ -1,36 +0,0 @@
-#press-bridge-button-img {
- width: 200px;
- margin: 0 auto 30px auto;
- display: inherit;
-}
-
-#bridge-button-group {
- width: 150px;
- margin: 30px auto;
- text-align: left;
-}
-
-#bridge-input md-input-container{
- max-width: 200px;
- margin: 30px auto 20px;
-}
-
-#bridge-finder {
- text-align: center;
- padding: 20px 15px 0;
- font-size: 16px;
- flex-direction: column;
- display: flex;
- justify-content: center;
- height: 100vh;
-}
-
-#bridge-finder .md-bar {
- background-color: $secondaryThemeColor !important;
-}
-
-.bridge-finder-bottom {
- margin-top: 30px;
- width: 100%;
- font-size: 18px;
-}
diff --git a/mobile/app/styles/common.scss b/mobile/app/styles/common.scss
deleted file mode 100644
index fe3e02c..0000000
--- a/mobile/app/styles/common.scss
+++ /dev/null
@@ -1,11 +0,0 @@
-.text-left {
- text-align: left !important;
-}
-
-.relative {
- position: relative !important;
-}
-
-.no-text-decoration {
- text-decoration: none !important;
-}
diff --git a/mobile/app/styles/dimmer.scss b/mobile/app/styles/dimmer.scss
deleted file mode 100644
index 2bea319..0000000
--- a/mobile/app/styles/dimmer.scss
+++ /dev/null
@@ -1,80 +0,0 @@
-div.dimmerOn {
- color: $whitish !important;
- background: $blackish !important;
-}
-
-html.dimmerOn {
- color: white;
- background: $blackish;
-}
-
-body.dimmerOn {
- color: $whitish;
- background: $blackish;
- md-dialog {
- background-color: rgba(0, 0, 0, 0.9) !important;
- }
- md-input-container {
- label {
- color: #3f51b5 !important;
- }
- .md-input {
- color: $whitish !important;
- border-color: #3f51b5 !important;
- }
- }
- .md-track {
- background: $whitish;
- }
- .color {
- border: 1px solid white;
- }
- .playlist-item, .ember-basic-dropdown-content md-menu-content {
- color: $whitish;
- background-color: $dimmerOnButtonColor;
- }
- .ember-basic-dropdown-content a {
- color: $whitish;
- }
- .playlist-item {
- &.active {
- background: darken($dimmerOnButtonColor, 15%) !important;
- }
- .audio-remove-button .paper-icon {
- color: $whitish !important;
- }
- }
- .light-inactive::before {
- display: none;
- }
-
- .hue-light {
- -webkit-filter: drop-shadow(0 0 5px #228DFF);
- fill: $whitish;
- path {
- fill: $whitish;
- }
- }
- .md-container {
- color: $whitish;
- }
- .add-new-music:hover {
- background: darken($dimmerOnButtonColor, 5%);
- }
- .md-bar {
- background-color: darken(white, 60%) !important;
- }
-}
-
-.paper-icon.dimmerOn {
- text-shadow: $glowingText;
- opacity: 0.9 !important;
-}
-
-#dimmer-container {
- float: left;
- cursor: pointer;
- padding: 5px 10px;
- position: relative;
- bottom: 5px;
-}
diff --git a/mobile/app/styles/hue-controls.scss b/mobile/app/styles/hue-controls.scss
deleted file mode 100644
index 8a75ebf..0000000
--- a/mobile/app/styles/hue-controls.scss
+++ /dev/null
@@ -1,82 +0,0 @@
-#lights-tab {
- padding: 0;
- margin-top: 5vh;
- .paper-icon {
- line-height: 0.8 !important;
- }
-}
-
-#hue-controls {
- max-width: 1200px;
- position: relative;
- min-height: 100vh;
- md-progress-circular {
- position: absolute;
- top: 50%;
- left: 50%;
- transform: translate(-50%, -50%);
- }
-}
-
-#navigation {
- padding: 15px 0 4vh;
- text-align: center;
- position: relative;
- .ember-basic-dropdown-trigger {
- z-index: 3;
- text-align: right;
- position: absolute;
- top: 5px;
- right: -10px;
- transform: scale(1.1);
- }
-}
-
-.navigation-item {
- font-size: 20px;
- padding: 0 10px 0 10px;
- &.active {
- font-weight: bold;
- text-decoration: none !important;
- }
-}
-
-.color {
- border: 1px solid rgb(164, 164, 164);
-}
-
-.color-row .md-list-item-inner {
- padding-right: 0;
-}
-
-#color-picker {
- padding: 5px;
- background: rgba(0, 0, 0, 0.7);
- box-shadow: 5px 10px 15px 5px rgba(0, 0, 0, 0.3);
- color: #FFFFFF;
- position: absolute;
- width: 266px;
- height: 266px;
- right: 6px;
- top: -9px;
- z-index: 3;
-}
-
-.color-content {
- box-shadow: none !important;
- md-menu-content, md-menu-item {
- background-color: transparent !important;
- }
-}
-
-#loop-addition {
- position: absolute;
- left: 33px;
- top: 15px;
- font-size: 16px !important;
-}
-
-#huegasm-content {
- height: 80%;
- max-height: 500px;
-}
diff --git a/mobile/app/styles/huegasm-variables.scss b/mobile/app/styles/huegasm-variables.scss
deleted file mode 100644
index 914abb3..0000000
--- a/mobile/app/styles/huegasm-variables.scss
+++ /dev/null
@@ -1,8 +0,0 @@
-$playerHeight: 400px;
-$playerDefaultIconColor: #BBBBBB;
-$secondaryThemeColor: #F12B24;
-$glowingText: 0 0 2px #fff, 0 0 4px #fff, 0 0 20px #228DFF;
-$dimmerOnButtonColor: #404040;
-$blackish: #242424;
-$whitish: #e0e0e0;
-$paperThemeColor: #3f51b5;
diff --git a/mobile/app/styles/introjs.scss b/mobile/app/styles/introjs.scss
deleted file mode 100644
index fc7b5a1..0000000
--- a/mobile/app/styles/introjs.scss
+++ /dev/null
@@ -1,18 +0,0 @@
-#settings.introjs-fixParent {
- position: inherit !important;
-}
-
-.introjs-tooltip {
- width: 300px;
-}
-
-.introjs-skipbutton {
- color: $secondaryThemeColor;
-}
-
-.introjs-bullets ul li a.active {
- position: relative;
- height: 10px;
- width: 10px;
- top: -2px;
-}
diff --git a/mobile/app/styles/light-group.scss b/mobile/app/styles/light-group.scss
deleted file mode 100644
index fb6bf21..0000000
--- a/mobile/app/styles/light-group.scss
+++ /dev/null
@@ -1,66 +0,0 @@
-.light-group {
- max-width: 800px;
- margin: 0 auto;
- display: flex;
- justify-content: center;
- flex-wrap: wrap;
-}
-
-.hue-light {
- width: 35px;
-}
-
-.toggleable-light {
- cursor: pointer;
- position: relative;
- border-radius: 30%;
- border: 2px solid $whitish;
- margin: 0 2px;
- display: flex;
- height: 50px;
- align-items: center;
- justify-content: center;
- padding: 3px;
-}
-
-.light-inactive {
- border-color: rgba($secondaryThemeColor, 0.4);
-}
-
-.light-inactive::before {
- font-weight: bold;
- position: absolute;
- top: -5px;
- content: "\e014";
- font-family: 'Glyphicons Halflings';
- font-size: 40px;
- color: rgba($secondaryThemeColor, 0.6);
-}
-
-.light-active {
- border-color: rgba(green, 0.4);
- .hue-light {
- transition-duration: 0.3s;
- transition-property: transform;
- box-shadow: 0 0 1px rgba(0, 0, 0, 0);
- }
-}
-
-.remove-button {
- margin: 10px 0 10px 60px;
-}
-
-.light-text {
- padding: 0 7px;
- &.light-inactive::before {
- left: 10px;
- }
-}
-
-.light-text-content {
- display: block;
- overflow: hidden;
- text-overflow: ellipsis;
- white-space: nowrap;
- max-width: 100px;
-}
\ No newline at end of file
diff --git a/mobile/app/styles/music-tab.scss b/mobile/app/styles/music-tab.scss
deleted file mode 100644
index b9655e3..0000000
--- a/mobile/app/styles/music-tab.scss
+++ /dev/null
@@ -1,360 +0,0 @@
-.row {
- margin: 0;
-}
-
-#music-tab {
- padding: 0;
- margin: 10px 0 20px;
-}
-
-#slide-toggle {
- font-size: 22px;
- color: $playerDefaultIconColor;
- background: #730B07;
- div .paper-icon {
- color: inherit !important;
- font-size: 24px;
- font-weight: bold;
- }
-}
-
-#player-controls {
- transition: all 0.2s ease-in-out;
- position: absolute;
- bottom: 0;
- left: 0;
- padding: 15px 10px;
- width: 100%;
- color: white !important;
- z-index: 20;
- background: linear-gradient(rgba(0, 0, 0, 0), rgba(0, 0, 0, 1));
- .ember-basic-dropdown-trigger {
- position: absolute;
- right: 0;
- bottom: 10px;
- }
- md-menu-item > .md-button md-icon {
- margin: auto 0 5px 10px;
- }
- .play-arrow, .pause, .replay {
- font-size: 30px;
- }
-}
-
-#player-time-controls {
- font-family: "Helvetica Neue", Helvetica, Arial, sans-serif;
- font-size: 14px;
- display: inline-block;
- margin-left: 1em;
-}
-
-.player-control-icon {
- color: $playerDefaultIconColor !important;
- transition-duration: 0.1s;
- margin-right: 10px;
- font-size: 22px;
-}
-
-.player-control-icon.active {
- color: $secondaryThemeColor !important;
-}
-
-#play-notification {
- position: relative;
- color: white !important;
- background: black;
- top: 50%;
- left: 50%;
- opacity: 0;
- border-radius: 100%;
-}
-
-#player-area {
- height: $playerHeight;
- background-color: black;
- display: inline-block;
- padding: 0;
-}
-
-#playlist {
- height: $playerHeight;
- background-color: #1E1E1E;
- padding: 0 5px 0 5px;
-}
-
-#player-area * .noUi-origin {
- background-color: $blackish;
- border-radius: 5px;
-}
-
-#player-area * .noUi-base {
- background-color: $blackish;
- border-radius: 5px;
-}
-
-#volume-bar {
- width: 5em;
- height: 0.5em;
- display: inline-block;
-}
-
-#player-area * .noUi-handle::after, #player-area * .noUi-handle::before {
- content: none;
-}
-
-#seek-slider {
- margin-bottom: 15px;
- transition-duration: 0.2s;
- height: 8px;
- .noUi-handle {
- opacity: 1 !important;
- }
-}
-
-#seek-slider * .noUi-handle {
- border: none;
- height: 13px;
- width: 13px;
- border-radius: 50%;
- top: -4px;
- left: -6px;
- opacity: 0;
- transition-duration: 0.1s;
- background-color: $secondaryThemeColor !important;
- box-shadow: none;
-}
-
-#play-list-controls {
- min-height: 40px;
- margin-top: 5px;
- border-bottom: 1px solid #3a3a3a;
- position: relative;
- font-size: 20px;
- button .player-control-icon {
- margin: 0 5px 1px 3px;
- }
- .ember-basic-dropdown-trigger {
- position: absolute;
- bottom: 0;
- right: 0;
- color: $whitish;
- .paper-button {
- margin: 0;
- }
- }
-}
-
-#play-list-area {
- background-color: white;
- width: 100%;
- height: 350px;
- margin: 0 auto;
- border-radius: 5px;
- transition: 0.1s all ease-in-out;
- position: relative;
- overflow: hidden;
- #dragHere {
- position: absolute;
- top: 27%;
- font-size: 20px;
- text-align: center;
- width: 100%;
- }
- [md-font-icon="library-music"] {
- position: absolute;
- top: 40%;
- font-size: 100px;
- opacity: 0.5;
- width: 100%;
- text-align: center;
- }
-}
-
-.song-artist {
- font-weight: bold;
-}
-
-#file-input {
- width: 1px;
- height: 1px;
- visibility: hidden;
-}
-
-.playlist-item {
- margin-right: 5px;
- border-bottom: 1px solid rgba(128, 128, 128, 0.3);
- border-top: 1px solid rgba(128,128,128,0.3);
- height: 62px;
- font-family: 'Open Sans', sans-serif;
- padding: 0 20px 0 5px;
- position: relative;
- color: $blackish;
- background: darken(white, 5%);
- .close {
- font-size: 18px;
- }
- .album-art {
- height: 60px;
- float: left;
- margin-right: 5px;
- border: 1px solid rgba(0, 0, 0, 0.5);
- }
- .song-info {
- .song-title {
- max-height: 40px;
- overflow: hidden;
- }
- .song-artist {
- max-height: 20px;
- overflow: hidden;
- }
- }
- .audio-remove-button {
- position: absolute;
- top: 10px;
- right: 0;
- padding: 10px;
- }
-}
-
-.playlist-item.active {
- background: darken(white, 15%) !important;
- border-top: 1px solid $secondaryThemeColor;
- border-bottom: 1px solid $secondaryThemeColor;
-}
-
-.playlist-item:hover {
- background: darken(white, 10%);
-}
-
-#beat-area {
- position: relative;
- padding: 0;
- margin-bottom: 20px;
-}
-
-#beat-option-button-group {
- margin: 20px 0 10px 0;
-}
-
-.beat-option {
- padding: 5px 0;
- text-align: center;
- md-switch {
- margin: 0;
- }
- .option-description {
- display: inline-flex;
- font-size: 20px;
- justify-content: center;
- flex-direction: column;
- }
- button {
- margin-top: 0;
- }
-}
-
-#player-bottom {
- color: $blackish;
- border: 1px solid black;
- width: 100%;
- background: white;
- border-bottom-left-radius: 5px;
- border-bottom-right-radius: 5px;
- .md-label {
- width: 100%;
- }
-}
-
-#add-music-choices {
- min-width: initial;
- right: 0;
- left: initial;
- width: 100px;
- top: 25px;
-}
-
-.add-new-music {
- padding: 0 5px 0 10px;
- font-size: 16px;
- border-radius: 5px;
- background: #f8f8f8;
- border: none;
-}
-
-.sound-cloud-link {
- position: absolute;
- right: 55px;
- bottom: 22px;
-}
-
-#visualization {
- position: absolute;
- top: 0;
- left: 0;
-}
-
-#save-beat-preferences-star {
- position: absolute;
- top: 3px;
- z-index: 1000;
- left: 5px;
- md-icon {
- color: $secondaryThemeColor !important;
- font-size: 25px;
- }
-}
-
-.visualizers-menu {
- left: -135px;
-}
-
-.display-icon {
- background: url(images/huegasm.png) center center no-repeat;
- background-size: 80px 80px;
-}
-
-#artwork {
- position: absolute;
- width: 100%;
- overflow: hidden;
- img {
- display: block;
- margin: 0 auto;
- max-height: 400px;
- }
-}
-
-.keyboard-arrow-down {
- font-size: 20px;
-}
-
-.visualizers-menu .paper-icon {
- margin-left: 10px;
- position: relative;
- top: -4px;
-}
-
-.close {
- font-size: 18px !important;
- color: rgb(51, 51, 51);
- text-shadow: none;
-}
-
-.ember-notify-default.ember-notify-cn {
- top: 0;
- bottom: initial;
-}
-
-#soundcloud-tutorial {
- width: 100%;
-}
-
-@media(max-width: 500px) {
- #sensitivity-settings .noUi-value-vertical {
- display: none;
- }
- .option-description {
- height: 55px;
- }
-}
\ No newline at end of file
diff --git a/mobile/app/styles/noui-slider.scss b/mobile/app/styles/noui-slider.scss
deleted file mode 100644
index 2182545..0000000
--- a/mobile/app/styles/noui-slider.scss
+++ /dev/null
@@ -1,44 +0,0 @@
-.noUi-value-vertical {
- margin-top: -10px;
- transform: none;
-}
-
-.noUi-value-vertical, .noUi-pips {
- color: inherit !important;
-}
-
-.noUi-vertical .noUi-handle {
- border: 1px solid #A3A0A0;
- width: 26px;
-}
-
-.noUi-vertical .noUi-handle:after, .noUi-vertical .noUi-handle:before{
- background: grey;
-}
-
-.noUi-connect {
- background-color: $secondaryThemeColor;
-}
-
-.noUi-horizontal .noUi-handle {
- width: 0.4em;
- height: 1.3em;
- left: -0.071em;
- top: -0.550em;
- transition-duration: 0.1s;
- background: $playerDefaultIconColor !important;
-}
-
-.noUi-target {
- margin: 0 auto;
-}
-
-.noUi-base {
- background-color: #ADADAD;
- border: 1px solid #797979;
-}
-
-.noUi-vertical {
- height: 200px;
- margin: 15px auto 10px;
-}
diff --git a/mobile/app/styles/paper.scss b/mobile/app/styles/paper.scss
deleted file mode 100644
index 503c437..0000000
--- a/mobile/app/styles/paper.scss
+++ /dev/null
@@ -1,55 +0,0 @@
-@import 'ember-paper';
-
-md-checkbox .md-icon, .md-off, .md-on {
- border-color: inherit !important;
-}
-
-md-checkbox.md-default-theme.md-checked .md-icon {
- background: $secondaryThemeColor;
-}
-
-md-checkbox .md-label {
- width: 125px;
- text-align: left;
-}
-
-.md-button {
- font-size: 13px;
- flex-direction: unset;
- span {
- width: 100%;
- }
-}
-
-.ember-basic-dropdown-trigger {
- outline: none !important;
-}
-
-md-progress-circular {
- margin: 0 auto 20px auto !important;
-}
-
-md-progress-linear {
- margin-bottom: 50px !important;
-}
-
-md-slider.md-default-theme .md-thumb:after {
- border-color: $secondaryThemeColor;
- background-color: $secondaryThemeColor;
-}
-
-md-icon {
- color: rgba(0, 0, 0, 0.54) !important;
-}
-
-md-switch.md-default-theme.md-checked .md-thumb {
- background-color: $secondaryThemeColor;
-}
-
-md-list-item {
- margin-bottom: 2vh;
-}
-
-.md-thumb-text {
- user-select: none;
-}
diff --git a/mobile/bower.json b/mobile/bower.json
deleted file mode 100644
index 62e171c..0000000
--- a/mobile/bower.json
+++ /dev/null
@@ -1,13 +0,0 @@
-{
- "name": "huegasm",
- "dependencies": {
- "JavaScript-ID3-Reader": "https://github.com/aadsm/JavaScript-ID3-Reader.git",
- "bootstrap-sass": "^3.3.5",
- "hammer.js": "^2.0.8",
- "intro.js": "^2.1.0",
- "locallyjs": "^0.3.2",
- "matchMedia": "^0.3.0",
- "velocity": "^1.3.1",
- "perfect-scrollbar": "^0.7.0"
- }
-}
diff --git a/mobile/config/environment.js b/mobile/config/environment.js
deleted file mode 100644
index 1d7d854..0000000
--- a/mobile/config/environment.js
+++ /dev/null
@@ -1,47 +0,0 @@
-/* jshint node: true */
-
-module.exports = function(environment) {
- var ENV = {
- modulePrefix: 'huegasm_mobile',
- podModulePrefix: 'huegasm_mobile/pods',
- environment,
- rootURL: '',
- locationType: 'hash',
- EmberENV: {
- FEATURES: {
- // Here you can enable experimental features on an ember canary build
- // e.g. 'with-controller': true
- }
- },
-
- APP: {
- // Here you can pass flags/options to your application instance
- // when it is created
- }
- };
-
- if (environment === 'development') {
- // ENV.APP.LOG_RESOLVER = true;
- // ENV.APP.LOG_ACTIVE_GENERATION = true;
- // ENV.APP.LOG_TRANSITIONS = true;
- // ENV.APP.LOG_TRANSITIONS_INTERNAL = true;
- // ENV.APP.LOG_VIEW_LOOKUPS = true;
- }
-
- if (environment === 'test') {
- // Testem prefers this...
- ENV.locationType = 'none';
-
- // keep test console output quieter
- ENV.APP.LOG_ACTIVE_GENERATION = false;
- ENV.APP.LOG_VIEW_LOOKUPS = false;
-
- ENV.APP.rootElement = '#ember-testing';
- }
-
- if (environment === 'production') {
-
- }
-
- return ENV;
-};
diff --git a/mobile/ember-cli-build.js b/mobile/ember-cli-build.js
deleted file mode 100644
index 52985b6..0000000
--- a/mobile/ember-cli-build.js
+++ /dev/null
@@ -1,26 +0,0 @@
-/* global require, module */
-var EmberApp = require('ember-cli/lib/broccoli/ember-app');
-var Funnel = require('broccoli-funnel');
-
-module.exports = function(defaults) {
- var app = new EmberApp(defaults);
- var extraAssets = new Funnel('bower_components/bootstrap-sass/assets/fonts/bootstrap/', {
- srcDir: '/',
- include: ['**'],
- destDir: '/fonts/bootstrap'
- });
-
- app.import('vendor/dancer.js');
- app.import('vendor/cie-rgb-converter.js');
-
- app.import('bower_components/intro.js/intro.js');
- app.import('bower_components/intro.js/introjs.css');
- app.import('bower_components/intro.js/themes/introjs-nassim.css');
- app.import('bower_components/JavaScript-ID3-Reader/dist/id3-minimized.js');
- app.import('bower_components/locallyjs/dist/locally.min.js');
- app.import('bower_components/velocity/velocity.js');
- app.import('bower_components/perfect-scrollbar/js/perfect-scrollbar.js');
- app.import('bower_components/perfect-scrollbar/css/perfect-scrollbar.css');
-
- return app.toTree(extraAssets);
-};
diff --git a/mobile/ember-cordova/cordova/config.xml b/mobile/ember-cordova/cordova/config.xml
deleted file mode 100644
index 0b65184..0000000
--- a/mobile/ember-cordova/cordova/config.xml
+++ /dev/null
@@ -1,40 +0,0 @@
-
-
- Huegasm
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/mobile/ember-cordova/cordova/hooks/README.md b/mobile/ember-cordova/cordova/hooks/README.md
deleted file mode 100644
index 574ad4c..0000000
--- a/mobile/ember-cordova/cordova/hooks/README.md
+++ /dev/null
@@ -1,23 +0,0 @@
-
-# Cordova Hooks
-
-Cordova Hooks represent special scripts which could be added by application and plugin developers or even by your own build system to customize cordova commands. See Hooks Guide for more details: http://cordova.apache.org/docs/en/edge/guide_appdev_hooks_index.md.html#Hooks%20Guide.
diff --git a/mobile/ember-cordova/cordova/platforms/.gitkeep b/mobile/ember-cordova/cordova/platforms/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/mobile/ember-cordova/cordova/plugins/.gitkeep b/mobile/ember-cordova/cordova/plugins/.gitkeep
deleted file mode 100644
index e69de29..0000000
diff --git a/mobile/ember-cordova/cordova/res/icon/android/hdpi.png b/mobile/ember-cordova/cordova/res/icon/android/hdpi.png
deleted file mode 100644
index 79e42ee3509179fc427415fa416c9c8702831f2f..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 4030
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
diff --git a/mobile/ember-cordova/cordova/res/icon/android/ldpi.png b/mobile/ember-cordova/cordova/res/icon/android/ldpi.png
deleted file mode 100644
index b980bfa99d5091216d5bd447064dc5d0a6bb77f1..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 1896
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
Ef@Ni;&j0`b
diff --git a/mobile/ember-cordova/cordova/res/icon/android/xxhdpi.png b/mobile/ember-cordova/cordova/res/icon/android/xxhdpi.png
deleted file mode 100644
index 279b93b785c0a891ea5416aa9683ffcc80f793c8..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 8637
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
GPyYw=B`IM5
diff --git a/mobile/ember-cordova/cordova/res/screen/android/land-hdpi.png b/mobile/ember-cordova/cordova/res/screen/android/land-hdpi.png
deleted file mode 100644
index b56e6d37bd8eac5e09ec10690d651f3123038d65..0000000000000000000000000000000000000000
GIT binary patch
literal 0
HcmV?d00001
literal 20041
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