├── src
├── app
│ ├── module
│ │ ├── news
│ │ │ ├── module.html
│ │ │ ├── _example.html
│ │ │ ├── module.css
│ │ │ └── module.js
│ │ ├── settings
│ │ │ ├── module.html
│ │ │ ├── module.css
│ │ │ ├── _example.html
│ │ │ └── module.js
│ │ ├── clock
│ │ │ ├── _example.html
│ │ │ ├── module.html
│ │ │ ├── module.css
│ │ │ └── module.js
│ │ ├── header
│ │ │ ├── _example.html
│ │ │ ├── module.html
│ │ │ ├── module.css
│ │ │ └── module.js
│ │ ├── set-alarm
│ │ │ ├── _example.html
│ │ │ ├── module.html
│ │ │ ├── module.css
│ │ │ └── module.js
│ │ └── ambient
│ │ │ └── module.js
│ ├── core
│ │ ├── app.data.js
│ │ ├── app.css
│ │ ├── app.layout.json
│ │ └── app.js
│ └── resources
│ │ ├── icons
│ │ ├── -128.ico
│ │ ├── -128.png
│ │ ├── -16.png
│ │ ├── -256.png
│ │ ├── -32.png
│ │ └── -64.png
│ │ └── fonts
│ │ ├── icomoon.eot
│ │ ├── icomoon.ttf
│ │ ├── icomoon.woff
│ │ ├── DIGITALDREAM-webfont.ttf
│ │ ├── DIGITALDREAM-webfont.woff
│ │ ├── fonts.css
│ │ ├── icomoon.svg
│ │ └── DIGITALDREAM-webfont.svg
├── index.html
└── package.json
├── .gitignore
├── imgs
├── dark-alarm.png
├── dark-clock.png
├── light-alarm.png
└── light-clock.png
├── package.json
├── license.md
└── README.md
/src/app/module/news/module.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | /bower_components/
2 | /node_modules/
3 | .brackets.json
4 | /build
5 | /cache/
6 |
--------------------------------------------------------------------------------
/src/app/module/settings/module.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/imgs/dark-alarm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/imgs/dark-alarm.png
--------------------------------------------------------------------------------
/imgs/dark-clock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/imgs/dark-clock.png
--------------------------------------------------------------------------------
/imgs/light-alarm.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/imgs/light-alarm.png
--------------------------------------------------------------------------------
/imgs/light-clock.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/imgs/light-clock.png
--------------------------------------------------------------------------------
/src/app/core/app.data.js:
--------------------------------------------------------------------------------
1 | //app.data is an empty object you can use that all modules will have access to.
2 |
3 |
4 |
--------------------------------------------------------------------------------
/src/app/module/settings/module.css:
--------------------------------------------------------------------------------
1 | /*
2 | CSS for the settings module.
3 | Do not leave file empty.
4 | */
5 |
--------------------------------------------------------------------------------
/src/app/resources/icons/-128.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/src/app/resources/icons/-128.ico
--------------------------------------------------------------------------------
/src/app/resources/icons/-128.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/src/app/resources/icons/-128.png
--------------------------------------------------------------------------------
/src/app/resources/icons/-16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/src/app/resources/icons/-16.png
--------------------------------------------------------------------------------
/src/app/resources/icons/-256.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/src/app/resources/icons/-256.png
--------------------------------------------------------------------------------
/src/app/resources/icons/-32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/src/app/resources/icons/-32.png
--------------------------------------------------------------------------------
/src/app/resources/icons/-64.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/src/app/resources/icons/-64.png
--------------------------------------------------------------------------------
/src/app/resources/fonts/icomoon.eot:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/src/app/resources/fonts/icomoon.eot
--------------------------------------------------------------------------------
/src/app/resources/fonts/icomoon.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/src/app/resources/fonts/icomoon.ttf
--------------------------------------------------------------------------------
/src/app/resources/fonts/icomoon.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/src/app/resources/fonts/icomoon.woff
--------------------------------------------------------------------------------
/src/app/resources/fonts/DIGITALDREAM-webfont.ttf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/src/app/resources/fonts/DIGITALDREAM-webfont.ttf
--------------------------------------------------------------------------------
/src/app/resources/fonts/DIGITALDREAM-webfont.woff:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/RIAEvangelist/insane-alarm/HEAD/src/app/resources/fonts/DIGITALDREAM-webfont.woff
--------------------------------------------------------------------------------
/src/app/module/clock/_example.html:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/app/module/header/_example.html:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/app/module/news/_example.html:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/app/module/settings/_example.html:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/app/module/set-alarm/_example.html:
--------------------------------------------------------------------------------
1 |
5 |
--------------------------------------------------------------------------------
/src/app/module/settings/module.js:
--------------------------------------------------------------------------------
1 | (
2 | function(){
3 | var moduleName='settings';
4 |
5 | function render(el){
6 |
7 | }
8 |
9 | exports(moduleName,render);
10 | }
11 | )();
12 |
--------------------------------------------------------------------------------
/src/app/module/news/module.css:
--------------------------------------------------------------------------------
1 | /*
2 | CSS for the news module.
3 | Do not leave file empty.
4 | */
5 |
6 | .news-module{
7 | position:absolute;
8 | top:30px;
9 | left:0;
10 | padding:10px 20px;
11 | width:calc(100% - 40px);
12 | font-size:20px;
13 | font:helvetica, ubuntu, arial;
14 | cursor:pointer;
15 | }
16 |
--------------------------------------------------------------------------------
/src/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
--------------------------------------------------------------------------------
/src/app/module/clock/module.html:
--------------------------------------------------------------------------------
1 |
2 |
4 | 0
5 |
6 |
8 | :
9 |
10 |
12 | 0
13 |
14 |
15 |
17 | Awake
18 |
19 |
21 | Snooze
22 |
23 |
--------------------------------------------------------------------------------
/src/app/module/header/module.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 | X
6 |
7 |
8 |
10 | [ _ ]
11 |
12 |
13 |
15 | _
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/src/app/core/app.css:
--------------------------------------------------------------------------------
1 | html,
2 | body{
3 | margin:0;
4 | padding:0;
5 | height:100%;
6 | width:100%;
7 | background:rgb(0,0,0);
8 | color:rgb(200,200,200);
9 | overflow:hidden;
10 | font-family:arial;
11 | }
12 |
13 | body{
14 | box-shadow:inset 0 0 28px rgb(100,100,100);
15 | -webkit-transition:background-color 500ms;
16 | transition:background-color 500ms;
17 | }
18 |
19 | body * {
20 | position:relative;
21 | }
22 |
23 | .hidden{
24 | display:none;
25 | }
26 |
--------------------------------------------------------------------------------
/src/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name" : "InsaneAlarm",
3 | "version" : "0.0.1",
4 | "main" : "index.html",
5 | "webkit": {
6 | "plugin": true
7 | },
8 | "window":{
9 | "title" : "Insane Alarm",
10 | "icon" : "app/resources/icons/-128.png",
11 | "height" : 700,
12 | "width" : 1000,
13 | "toolbar": false,
14 | "frame" : false
15 | },
16 | "chromium-args": "--ppapi-flash-path=/opt/google/chrome-beta/PepperFlash/libpepflashplayer.so"
17 | }
18 |
--------------------------------------------------------------------------------
/src/app/module/set-alarm/module.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
5 |
6 | Hour
7 |
8 |
12 |
13 |
14 |
16 |
17 | Minute
18 |
19 |
23 |
24 |
25 |
26 |
27 | ${hourDisplay}
28 |
29 |
30 |
31 |
32 |
33 | ${min}
34 |
35 |
36 |
--------------------------------------------------------------------------------
/src/app/module/header/module.css:
--------------------------------------------------------------------------------
1 | /*
2 | CSS for the header module.
3 | Do not leave file empty.
4 | */
5 |
6 | .header-module{
7 | -webkit-app-region: drag;
8 | height:30px;
9 | width:100%;
10 | cursor:pointer;
11 | background:rgba(40,40,40,.7);
12 | position:fixed;
13 | top:0;
14 | left:0;
15 | z-index:10000;
16 | }
17 |
18 | .header-module div{
19 | -webkit-app-region: no-drag;
20 | float:right;
21 | background:rgb(100,100,100);
22 | color:rgb(0,0,0);
23 | border:none;
24 | height:20px;
25 | width:20px;
26 | line-height:20px;
27 | margin:5px;
28 | text-align:center;
29 | border-radius:5px;
30 | }
31 |
32 | .header-module .icon-cog{
33 | display:none;
34 | }
35 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "insane-alarm",
3 | "version": "1.0.0",
4 | "description": "Alarm which will wake you up no matter what!",
5 | "main": "./src/",
6 | "scripts": {
7 | "test": "echo \"Error: no test specified\" && exit 1"
8 | },
9 | "repository": {
10 | "type": "git",
11 | "url": "https://github.com/RIAEvangelist/insane-alarm.git"
12 | },
13 | "keywords": [
14 | "alarm",
15 | "insane",
16 | "loud",
17 | "clock",
18 | "wake",
19 | "up"
20 | ],
21 | "author": "Brandon Noazaki Miller",
22 | "license": "DBAD",
23 | "bugs": {
24 | "url": "https://github.com/RIAEvangelist/insane-alarm/issues"
25 | },
26 | "homepage": "https://github.com/RIAEvangelist/insane-alarm",
27 | "dependencies": {
28 | "nw-builder": "^2.0.2"
29 | }
30 | }
31 |
--------------------------------------------------------------------------------
/src/app/module/header/module.js:
--------------------------------------------------------------------------------
1 | (
2 | function(){
3 | var moduleName='header';
4 |
5 | function render(el){
6 | el.addEventListener(
7 | 'click',
8 | function(e){
9 | if(
10 | !win[e.target.id] &&
11 | e.target.id != 'setAlarm' &&
12 | e.target.id != 'settings' &&
13 | e.target.id != 'home'
14 | ){
15 | return;
16 | }
17 |
18 | switch(e.target.id){
19 | case 'setAlarm' :
20 | case 'settings' :
21 | case 'home' :
22 | app.navigate(e.target.id);
23 | break;
24 | default :
25 | win[e.target.id]();
26 | }
27 | }
28 | );
29 | }
30 |
31 | exports(moduleName,render);
32 | }
33 | )();
34 |
--------------------------------------------------------------------------------
/src/app/core/app.layout.json:
--------------------------------------------------------------------------------
1 | {
2 | "startAt":"home",
3 | "lib" : [
4 | {
5 | "path":"app/core/app.css",
6 | "type":"css"
7 | },
8 | {
9 | "path":"app/resources/fonts/fonts.css",
10 | "type":"css"
11 | },
12 | {
13 | "path":"app/core/app.data.js",
14 | "type":"js"
15 | },
16 | {
17 | "path":"app/core/app.layout.js",
18 | "type":"js"
19 | }
20 | ], "modules":{
21 | "logic":[
22 | "ambient"
23 | ],
24 | "ui" : {
25 | "home" : {
26 | "header" : {},
27 | "clock" : {},
28 | "news" : {}
29 | },
30 | "setAlarm" : {
31 | "header" : {},
32 | "set-alarm": {}
33 | },
34 | "settings" : {
35 | "header" : {},
36 | "settings": {}
37 | }
38 | }
39 | }
40 | }
41 |
--------------------------------------------------------------------------------
/license.md:
--------------------------------------------------------------------------------
1 | # DON'T BE A DICK PUBLIC LICENSE
2 |
3 | > Version 1, December 2009
4 |
5 | > Copyright (C) 2009 Philip Sturgeon
6 |
7 | Everyone is permitted to copy and distribute verbatim or modified
8 | copies of this license document, and changing it is allowed as long
9 | as the name is changed.
10 |
11 | > DON'T BE A DICK PUBLIC LICENSE
12 | > TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
13 |
14 | 1. Do whatever you like with the original work, just don't be a dick.
15 |
16 | Being a dick includes - but is not limited to - the following instances:
17 |
18 | 1a. Outright copyright infringement - Don't just copy this and change the name.
19 | 1b. Selling the unmodified original with no work done what-so-ever, that's REALLY being a dick.
20 | 1c. Modifying the original work to contain hidden harmful content. That would make you a PROPER dick.
21 |
22 | 2. If you become rich through modifications, related works/services, or supporting the original work,
23 | share the love. Only a dick would make loads off this work and not buy the original work's
24 | creator(s) a pint.
25 |
26 | 3. Code is provided with no warranty. Using somebody else's code and bitching when it goes wrong makes
27 | you a DONKEY dick. Fix the problem yourself. A non-dick would submit the fix back.
28 |
--------------------------------------------------------------------------------
/src/app/resources/fonts/fonts.css:
--------------------------------------------------------------------------------
1 | /* Generated by Font Squirrel (http://www.fontsquirrel.com) on May 27, 2013 03:28:33 PM America/New_York */
2 | body{
3 | /* Better Font Rendering =========== */
4 | -webkit-font-smoothing: antialiased;
5 | }
6 |
7 |
8 | @font-face {
9 | font-family: 'DigitaldreamRegular';
10 | src: url('DIGITALDREAM-webfont.woff') format('woff'),
11 | url('DIGITALDREAM-webfont.ttf') format('truetype'),
12 | url('DIGITALDREAM-webfont.svg#DigitaldreamRegular') format('svg');
13 | font-weight: normal;
14 | font-style: normal;
15 |
16 | }
17 |
18 | @font-face {
19 | font-family: 'icomoon';
20 | src:url('icomoon.eot?-1110p');
21 | src:url('icomoon.eot?#iefix-1110p') format('embedded-opentype'),
22 | url('icomoon.woff?-1110p') format('woff'),
23 | url('icomoon.ttf?-1110p') format('truetype'),
24 | url('icomoon.svg?-1110p#icomoon') format('svg');
25 | font-weight: normal;
26 | font-style: normal;
27 | }
28 |
29 | [class^="icon-"], [class*=" icon-"] {
30 | font-family: 'icomoon';
31 | speak: none;
32 | font-style: normal;
33 | font-weight: normal;
34 | font-variant: normal;
35 | text-transform: none;
36 | line-height: 1;
37 | }
38 |
39 | .icon-clock:before {
40 | content: "\e602";
41 | }
42 | .icon-bell:before {
43 | content: "\e600";
44 | }
45 | .icon-cog:before {
46 | content: "\e601";
47 | }
48 |
--------------------------------------------------------------------------------
/src/app/module/clock/module.css:
--------------------------------------------------------------------------------
1 | /*
2 | CSS for the clock module.
3 | Do not leave file empty.
4 | */
5 |
6 | .clock-module{
7 | font-size: 200px;
8 | font-family: 'DigitaldreamRegular';
9 | color: rgb(255, 75, 75);
10 | text-align: center;
11 | padding: 50px;
12 | height:100%;
13 | }
14 |
15 | .clock-module .hour,
16 | .clock-module .minute,
17 | .clock-module .seperator{
18 | width:calc(50% - 50px);
19 | position:absolute;
20 | top:calc(50% - 150px);
21 | }
22 | .clock-module .hour{
23 | left:0;
24 | width:calc(50% - 70px);
25 | text-align:right;
26 | }
27 | .clock-module .seperator{
28 | left:calc(50% - 70px);
29 | width:140px;
30 | text-align:center;
31 | }
32 | .clock-module .minute{
33 | right:0;
34 | width:calc(50% - 70px);
35 | text-align:left;
36 | }
37 |
38 | .clock-module .snooze,
39 | .clock-module .awake{
40 | font-size: 40px;
41 | padding: 20px;
42 | background: rgba(130,130,130,.7);
43 | margin: 20px;
44 | position: absolute;
45 | border-radius: 20px;
46 | box-shadow: 0 0 20px rgba(255,0,0,.7);
47 | color: rgb(255,0,0);
48 | text-shadow: 0 0 6px rgb(0,0,0);
49 | bottom:100px;
50 | display:none;
51 | }
52 |
53 | .clock-module.waitingToBeKilled .snooze,
54 | .clock-module.waitingToBeKilled .awake{
55 | display:block;
56 | }
57 |
58 | .clock-module .snooze{
59 | left:0;
60 | }
61 |
62 | .clock-module .awake{
63 | right:0;
64 | }
65 |
--------------------------------------------------------------------------------
/src/app/module/set-alarm/module.css:
--------------------------------------------------------------------------------
1 | /*
2 | CSS for the set-alarm module.
3 | Do not leave file empty.
4 | */
5 | .set-alarm-module{
6 | position:absolute;
7 | top:30px;
8 | width:100%;
9 | height:calc(100% - 30px);
10 | }
11 |
12 | .set-alarm-module ul{
13 | list-style:none;
14 | margin:0;
15 | padding:0;
16 | }
17 |
18 | .set-alarm-module .setHours{
19 | position:absolute;
20 | width:46%;
21 | height:100%;
22 | left:2%;
23 | }
24 |
25 | .set-alarm-module .setMins{
26 | position:absolute;
27 | width:46%;
28 | height:100%;
29 | left:52%;
30 | }
31 |
32 | .set-alarm-module .title{
33 | height:20px;
34 | line-height:20px;
35 | font-size:18px;
36 | }
37 |
38 | .set-alarm-module ul{
39 | height:calc(100% - 20px);
40 | }
41 |
42 | .set-alarm-module .setHours li{
43 | width:23%;
44 | height:14%;
45 | margin:1%;
46 | display:inline-block;
47 | background:rgb(50,50,50);
48 | text-align:center;
49 | line-height:65px;
50 | font-size:30px;
51 | overflow:hidden;
52 | cursor:pointer;
53 | transition:color 300ms, background-color 300ms;
54 | }
55 |
56 | .set-alarm-module .setMins li{
57 | width:13%;
58 | height:7.6%;
59 | margin:1%;
60 | display:inline-block;
61 | background:rgb(50,50,50);
62 | text-align:center;
63 | line-height:40px;
64 | font-size:24px;
65 | overflow:hidden;
66 | cursor:pointer;
67 | transition:color 300ms, background-color 300ms;
68 | }
69 |
70 | .set-alarm-module li:hover{
71 | background:rgb(180,200,180);
72 | color:rgb(50,50,50);
73 | }
74 |
75 | .set-alarm-module li.selected{
76 | background:rgb(100,150,100);
77 | }
78 |
--------------------------------------------------------------------------------
/src/app/module/clock/module.js:
--------------------------------------------------------------------------------
1 | (
2 | function(){
3 | var moduleName='clock';
4 |
5 | function render(el){
6 | setInterval(
7 | showTime,
8 | 1000
9 | );
10 |
11 | showTime();
12 |
13 | setTimeout(
14 | function(){
15 | Object.observe(
16 | app.data.alarm,
17 | function(data){
18 | for(var val of data){
19 | var clock=document.getElementById('clock-module');
20 | if(!val.object.waitingToBeKilled){
21 | clock.classList.remove('waitingToBeKilled');
22 | return;
23 | }
24 | clock.classList.add('waitingToBeKilled');
25 | }
26 | }
27 | );
28 | },
29 | 100
30 | )
31 |
32 | el.addEventListener(
33 | 'click',
34 | function(e){
35 | switch(e.target.id){
36 | case 'snooze' :
37 | app.trigger('snooze');
38 | break;
39 | case 'awake' :
40 | app.trigger('awake');
41 | break;
42 | default :
43 | return;
44 | }
45 | }
46 | );
47 | }
48 |
49 | function showTime(){
50 | var date=new Date();
51 | var hour=date.getHours();
52 | var min=date.getMinutes();
53 |
54 | app.data.time={
55 | hour: hour,
56 | min : min
57 | }
58 |
59 | if(hour>12 && !app.data.military)
60 | hour=hour-12;
61 |
62 | document.getElementById('hour').innerHTML=hour;
63 | document.getElementById('minute').innerHTML=('0'+min).slice(-2);
64 | }
65 |
66 | exports(moduleName,render);
67 | }
68 | )();
69 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Insane Alarm!
2 | This is a desktop port (nw.js) of my very first chrome app programmed one night when my wife was away. I had spent a night out with the boys and drank a bit too much but needed to be up in the morning. I realised that my phone was dead and I didn't have a charger, and my internet was unreliable at the time so none of the apps out there seemed like they would wake me up reliably.
3 |
4 | So I naturally did what any programmer would do, I programmed my own, with the LOUDEST alarm based off of an emergency alarm from when I was in the military. I couldn't find a good sound to match it in my intoxicated state... so I made my own using the Web Audio Context and Oscillator nodes.
5 |
6 | It supports Windows, Mac and Linux.
7 |
8 | ## Download Alarm
9 | Download the program or binaries for your system from our [insane alarm releases](https://github.com/RIAEvangelist/insane-alarm/releases)
10 |
11 | ## Support by Purchasing alarm
12 | #### [insane alarm](https://gum.co/insane-alarm) on gumroad.com
13 | If this alarm has saved your but, woken you, your spouse, children, animals and or neighbors up, please take a moment to show this app is worth a dollar to you! Its just a buck, you probably have lost 10x that much between the center console and your seat in the car. Show some love!
14 |
15 | ## Features
16 | 1. Loud as hell!
17 | 2. Adjusts brightness and colors based on ambient light.
18 | 3. Easy to use alarm settings.
19 | 4. Displays news headlines from CNN.
20 |
21 | ## Alarm screenshots
22 | 
23 | 
24 | 
25 | 
26 |
27 | ## Building from src
28 | 1. You will need nodejs installed.
29 | 2. run ` npm install ` from the insane-alarm directory (not the src directory). This should ` npm install nw-builder ` for the build script
30 | 3. run ` node build.js ` from the insane alarm directory.
31 | 4. run your build from the build folder created!
32 |
33 | ## Licensed under DBAD license
34 | See the [DBAD license](https://github.com/philsturgeon/dbad) in your language or our [licence.md](https://github.com/RIAEvangelist/insane-alarm/blob/master/license.md) file.
35 |
--------------------------------------------------------------------------------
/src/app/resources/fonts/icomoon.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
14 |
--------------------------------------------------------------------------------
/src/app/module/ambient/module.js:
--------------------------------------------------------------------------------
1 | (
2 | function(){
3 | var moduleName='ambient';
4 |
5 | navigator.getUserMedia = ( navigator.getUserMedia ||
6 | navigator.webkitGetUserMedia ||
7 | navigator.mozGetUserMedia ||
8 | navigator.msGetUserMedia);
9 |
10 | function render(el){
11 | window.video = document.createElement('video'),
12 | window.canvas = document.createElement('canvas'),
13 | window.ctx = canvas.getContext('2d');
14 |
15 | var constraints={
16 | video: {
17 | mandatory: {
18 | maxHeight : 1,
19 | maxWidth : 1,
20 | maxFrameRate : 1
21 | }
22 | }
23 | }
24 |
25 | navigator.getUserMedia(
26 | constraints,
27 | function(localMediaStream){
28 | window.localMediaStream=localMediaStream;
29 | video.src = window.URL.createObjectURL(window.localMediaStream);
30 | video.play();
31 | },
32 | function(err){
33 | console.log(err);
34 | }
35 | );
36 |
37 | setTimeout(
38 | renderAmbient,
39 | 100
40 | );
41 |
42 | setInterval(
43 | renderAmbient,
44 | 1000
45 | );
46 | }
47 |
48 | function renderAmbient(){
49 | ctx.drawImage(video, 0, 0);
50 |
51 | var frame = ctx.getImageData(0, 0, canvas.width, canvas.height);
52 |
53 | var brightness=Math.floor(
54 | (
55 | frame.data[0]+
56 | frame.data[1]+
57 | frame.data[2]
58 | )/3
59 | );
60 |
61 | var use=240;
62 | var text=0;
63 |
64 | if(brightness<180){
65 | use=100;
66 | }
67 |
68 | if(brightness<110){
69 | use=0;
70 | color=130;
71 | }
72 |
73 | if(brightness<70){
74 | use=0;
75 | color=40;
76 | }
77 |
78 | var rgb='rgb('+(new Array(4).join(use+',').slice(0,-1))+')';
79 | var rgbText='rgb('+(new Array(4).join(color+',').slice(0,-1))+')';
80 |
81 | app.data.ambient={
82 | rgb:rgb,
83 | rgbText:rgbText
84 | }
85 |
86 | document.querySelector('body').style.backgroundColor=rgb;
87 | document.querySelector('.clock-module').style.color=
88 | document.querySelector('.news-module').style.color=rgbText;
89 |
90 | return;
91 | }
92 |
93 |
94 | exports(moduleName,render);
95 | }
96 | )();
97 |
--------------------------------------------------------------------------------
/src/app/module/news/module.js:
--------------------------------------------------------------------------------
1 | (
2 | function(){
3 | var moduleName='news';
4 | var newsTimer=false;
5 | var news=false;
6 |
7 | function render(el){
8 | fetchCNN();
9 | el.addEventListener(
10 | 'click',
11 | function(e){
12 | Window.open(
13 | e.target.getAttribute('href'),
14 | {
15 | frame:true,
16 | toolbar:true,
17 | focus:true
18 | }
19 | );
20 | }
21 | );
22 |
23 | setInterval(
24 | fetchCNN,
25 | 1200000//20 min
26 | );
27 | }
28 |
29 | function fetchCNN(){
30 | news=document.getElementById('news-module');
31 | if(!navigator.onLine){
32 | news.innerHTML='CNN not available in offline mode...';
33 | return;
34 | }
35 |
36 | clearInterval(
37 | newsTimer
38 | );
39 |
40 | var xhr = new XMLHttpRequest();
41 | xhr.onload = function(e) {
42 | var jss = xmlToJson(e.target.responseXML.documentElement);
43 | news.innerHTML=jss.channel.title['#text'];
44 | var currentNews=0;
45 |
46 | news.setAttribute('href',jss.channel.item[currentNews].link['#text']);
47 | news.innerHTML='CNN : '+jss.channel.item[currentNews].title['#text'];
48 | newsTimer=setInterval(
49 | function(){
50 | var index=currentNews++ % jss.channel.item.length;
51 | news.setAttribute('href',jss.channel.item[index].link['#text']);
52 | news.innerHTML='CNN : '+jss.channel.item[index].title['#text'];
53 | },
54 | 25000
55 | )
56 |
57 | }
58 | xhr.open("GET", "http://rss.cnn.com/rss/cnn_latest.rss");
59 | xhr.send();
60 | }
61 |
62 | function xmlToJson(xml) {
63 |
64 | var obj = {};
65 |
66 | if (xml.nodeType == 1) {
67 | if (xml.attributes.length > 0) {
68 | obj["@attributes"] = {};
69 | for (var j = 0; j < xml.attributes.length; j++) {
70 | var attribute = xml.attributes.item(j);
71 | obj["@attributes"][attribute.nodeName] = attribute.value;
72 | }
73 | }
74 | } else if (xml.nodeType == 3) { // text
75 | obj = xml.nodeValue;
76 | }
77 |
78 | if (xml.hasChildNodes()) {
79 | for(var i = 0; i < xml.childNodes.length; i++) {
80 | var item = xml.childNodes.item(i);
81 | var nodeName = item.nodeName;
82 | if (typeof(obj[nodeName]) == "undefined") {
83 | obj[nodeName] = xmlToJson(item);
84 | } else {
85 | if (typeof(obj[nodeName].push) == "undefined") {
86 | var old = obj[nodeName];
87 | obj[nodeName] = [];
88 | obj[nodeName].push(old);
89 | }
90 | obj[nodeName].push(xmlToJson(item));
91 | }
92 | }
93 | }
94 | return obj;
95 | };
96 |
97 | exports(moduleName,render);
98 | }
99 | )();
100 |
--------------------------------------------------------------------------------
/src/app/module/set-alarm/module.js:
--------------------------------------------------------------------------------
1 | (
2 | function(){
3 | var moduleName='set-alarm';
4 | app.data.alarm={};
5 |
6 | window.AudioContext = (
7 | window.AudioContext ||
8 | window.webkitAudioContext
9 | );
10 |
11 | window.alarm=
12 | alarm={};
13 | alarm.context=new AudioContext();
14 | alarm.mainVolume=alarm.context.createGain();
15 | alarm.mainVolume.connect(alarm.context.destination);
16 |
17 | alarm.toneLength=1000;
18 | alarm.toneBreakLength=300;
19 | alarm.sound={
20 | low: {
21 | hertz : 200
22 | },
23 | mid: {
24 | hertz : 500
25 | },
26 | high: {
27 | hertz : 1000
28 | }
29 | };
30 |
31 | function render(el){
32 | var hourOptions=document.getElementById('hourOptions');
33 | var minOptions=document.getElementById('minOptions');
34 |
35 | el.addEventListener(
36 | 'click',
37 | function(e){
38 | if(!e.target.tagName.toLowerCase()=='li')
39 | return;
40 |
41 | var currentSelection=e.target.parentElement.querySelector('.selected')
42 |
43 | if(currentSelection)
44 | currentSelection.classList.remove('selected');
45 |
46 | e.target.classList.add('selected');
47 |
48 | setAlarm();
49 | }
50 | );
51 |
52 | for(var i=0; i<24; i++){
53 | var hour=i;
54 |
55 | if(hour==0)
56 | hour=12;
57 |
58 | if(i<12)
59 | hour+='AM'
60 |
61 | if(i>11){
62 | if(i>12)
63 | hour=i-12;
64 | hour+='PM'
65 | }
66 |
67 | var option=app.template(
68 | 'hour-option',
69 | {
70 | hour:i,
71 | hourDisplay:hour
72 | }
73 | )
74 |
75 | hourOptions.appendChild(
76 | option
77 | )
78 | }
79 |
80 | for(var i=0; i<60; i++){
81 | var option=app.template(
82 | 'min-option',
83 | {
84 | min:i
85 | }
86 | )
87 |
88 | minOptions.appendChild(
89 | option
90 | )
91 | }
92 |
93 | setTimeout(
94 | initAlarm,
95 | 100
96 | );
97 | }
98 |
99 | function loadPrefrences(){
100 | app.storage.get(
101 | null,
102 | function(data){
103 | app.data.alarm=data;
104 | app.data.alarm.killed=false;
105 | if(!app.data.alarm.hour)
106 | app.data.alarm.hour=7;
107 |
108 | if(!app.data.alarm.min)
109 | app.data.alarm.min=30;
110 |
111 | //chrome.power.requestKeepAwake("system");
112 | }
113 | );
114 | }
115 | loadPrefrences();
116 |
117 | function initAlarm(){
118 | if(
119 | !!!app.data.alarm.hour ||
120 | !!!app.data.alarm.min
121 | ){
122 | return;
123 | }
124 |
125 | document.querySelector('[hour="'+app.data.alarm.hour+'"]').classList.add('selected');
126 | document.querySelector('[min="'+app.data.alarm.min+'"]').classList.add('selected');
127 |
128 | setInterval(
129 | checkAlarm,
130 | alarm.toneLength+alarm.toneBreakLength
131 | );
132 |
133 | }
134 |
135 | function setAlarm(){
136 | var times=document.querySelectorAll('.selected');
137 | if(times.length<2)
138 | return;
139 |
140 | var alarmData={
141 | hour: times[0].getAttribute('hour'),
142 | min : times[1].getAttribute('min')
143 | }
144 |
145 | app.storage.set(
146 | alarmData
147 | );
148 |
149 | app.data.alarm.hour=alarmData.hour;
150 | app.data.alarm.min=alarmData.min;
151 | }
152 |
153 | function checkAlarm(){
154 | document.body.style.backgroundColor=app.data.ambient.rgb;
155 | if(
156 | (
157 | !app.data.alarm.waitingToBeKilled &&
158 | (
159 | Number(app.data.time.hour)!= Number(app.data.alarm.hour) ||
160 | Number(app.data.time.min) != Number(app.data.alarm.min)
161 | )
162 | ) ||
163 | app.data.alarm.killed
164 | ){
165 | return;
166 | }
167 |
168 | document.body.style.backgroundColor='rgb(255,255,255)';
169 |
170 | app.data.alarm.waitingToBeKilled=true;
171 | app.data.alarm.killed=false;
172 |
173 | app.navigate('home');
174 |
175 | win.focus();
176 | win.enterFullscreen();
177 |
178 | //chrome.power.requestKeepAwake("display");
179 |
180 | for (i in alarm.sound) {
181 | if(!alarm.oscillators)
182 | break;
183 | var oscillator=alarm.oscillators[i];
184 | if(!oscillator)
185 | continue;
186 | if(!oscillator.tone)
187 | continue;
188 | oscillator.tone.stop(0);
189 | };
190 |
191 | alarm.oscillators={};
192 |
193 | for (var i in alarm.sound) {
194 | var oscillator,
195 | tone=alarm.sound[i];
196 |
197 | alarm.oscillators[i]={};
198 | oscillator=alarm.oscillators[i];
199 | oscillator.tone=alarm.context.createOscillator();
200 | oscillator.volume=alarm.context.createGain();
201 | oscillator.tone.type=0;
202 | oscillator.tone.frequency.value=tone.hertz;
203 | oscillator.tone.connect(oscillator.volume);
204 | oscillator.volume.connect(alarm.mainVolume);
205 | }
206 |
207 | for (i in alarm.sound) {
208 | var oscillator=alarm.oscillators[i];
209 | oscillator.tone.start(0);
210 | }
211 |
212 | clearTimeout(alarm.beat);
213 | alarm.beat=setTimeout(
214 | function(){
215 | for (i in alarm.sound) {
216 | var oscillator=alarm.oscillators[i];
217 | if(!oscillator)
218 | continue;
219 | if(!oscillator.tone)
220 | continue;
221 | oscillator.tone.stop(0);
222 | };
223 | document.body.style.backgroundColor=app.data.ambient.rgb;
224 | },
225 | alarm.toneLength
226 | );
227 | }
228 |
229 | function killAlarm(){
230 | app.data.alarm.killed=true;
231 | app.data.alarm.waitingToBeKilled=false;
232 | resetAlarm(true);
233 | }
234 |
235 | function snoozeAlarm(){
236 | app.data.alarm.killed=true;
237 | app.data.alarm.waitingToBeKilled=false;
238 | app.data.alarm.min=Number(app.data.alarm.min)+5;
239 | if(app.data.alarm.min>59){
240 | app.data.alarm.hour=Number(app.data.alarm.hour)+1;
241 | if(app.data.alarm.hour>23)
242 | app.data.alarm.hour=0;
243 |
244 | app.data.alarm.min-=60;
245 | }
246 | resetAlarm();
247 | }
248 |
249 | function resetAlarm(hardReset){
250 | setTimeout(
251 | function(){
252 | app.data.alarm.killed=false;
253 | },
254 | 55000
255 | );
256 |
257 | if(!hardReset)
258 | return;
259 |
260 | setTimeout(
261 | loadPrefrences,
262 | 60000
263 | );
264 | }
265 |
266 | app.on(
267 | 'awake',
268 | killAlarm
269 | );
270 |
271 | app.on(
272 | 'snooze',
273 | snoozeAlarm
274 | )
275 |
276 | exports(moduleName,render);
277 | }
278 | )();
279 |
--------------------------------------------------------------------------------
/src/app/resources/fonts/DIGITALDREAM-webfont.svg:
--------------------------------------------------------------------------------
1 |
2 |
3 |
139 |
--------------------------------------------------------------------------------
/src/app/core/app.js:
--------------------------------------------------------------------------------
1 | /**
2 | * @fileOverview app framework
3 | * @module core
4 | */
5 |
6 | /**
7 | * check for chrome variable to be defnined (safary)
8 | */
9 | if (typeof chrome === 'undefined') {
10 | chrome = false;
11 | }
12 |
13 | /**
14 | * @class app
15 | * @type Function|app_L10.appAnonym$2
16 | */
17 | var app = (
18 | function(){
19 |
20 | /************\
21 | Scope
22 | \************/
23 | var config={
24 | corePath: 'app/core/',
25 | modulesPath : 'app/module/',
26 | };
27 |
28 |
29 | var modules,
30 | constructors={},
31 | moduleQueue = {},
32 | events=[],
33 | dataStore={
34 | hasWebkitSpeech:(document.createElement('input').hasOwnProperty('webkitSpeech')),
35 | hasSpeech:(document.createElement('input').hasOwnProperty('speech')),
36 | HTML:{},
37 | JS:{},
38 | CSS:{}
39 | };
40 |
41 | if (!history) {
42 | history = {};
43 | }
44 |
45 | if (!history.pushState) {
46 | history.pushState = function (stateObject, screen) {
47 | history.state = stateObject;
48 | };
49 | history.state = {};
50 | }
51 |
52 | /**
53 | * set config object base on user config properties
54 | *
55 | * @memberOf app
56 | * @function setConfig
57 | * @param {object} userConfig
58 | * @returns {void}
59 | */
60 | function setConfig(userConfig) {
61 | for (var property in userConfig) {
62 | if (userConfig.hasOwnProperty('property')) {
63 | config[property] = userConfig[property];
64 | } else {
65 | return;
66 | }
67 | }
68 | }
69 |
70 | /************\
71 | Modules
72 | \************/
73 | /**
74 | * get module list base on html class element
75 | *
76 | * @memberOf app
77 | * @function getModules
78 | * @returns {void}
79 | */
80 | function getModules() {
81 | modules = document.getElementsByClassName('appModule');
82 | }
83 |
84 | /**
85 | * method to build modules
86 | *
87 | * @memberOf app
88 | * @function buildModules
89 | * @param {object} elements
90 | * @returns {void}
91 | */
92 | function buildModules(elements) {
93 | if (!elements) {
94 | elements = modules;
95 | if (!elements) {
96 | elements = [];
97 | }
98 | }
99 |
100 | if (!elements[0]) {
101 | elements = [elements];
102 | }
103 |
104 | if( !elements[0].getAttribute) {
105 | return;
106 | }
107 |
108 | var moduleCount=elements.length;
109 |
110 | for(var i=0; i-1){
315 | modules[i].classList.remove('hidden');
316 | continue;
317 | }
318 |
319 | modules[i].classList.add('hidden');
320 | }
321 |
322 | triggerEvent(
323 | 'app.navigated',
324 | stateObject
325 | );
326 |
327 | history.pushState(
328 | stateObject,
329 | screen,
330 | '#'+screen
331 | );
332 | }
333 |
334 | // if app.navigate event triggered, we want to show module group
335 | registerEvent('app.navigate', showModuleGroup);
336 |
337 | window.addEventListener(
338 | 'popstate',
339 | function(e){
340 | var state = e.state;
341 | if (!state) {
342 | state = {};
343 | }
344 |
345 | if (!state.screen) {
346 | state.screen = document.location.hash.slice(1);
347 | }
348 |
349 | showModuleGroup(state.screen, state);
350 | }
351 | );
352 |
353 | /**
354 | * initialize layout base on the layout object injected
355 | *
356 | * @memberOf app
357 | * @function layoutAppt
358 | * @param {object} layout object that represent layout and logic
359 | * @returns {void}
360 | * @see app.layout.json
361 | * @see loadLayout
362 | */
363 | function layoutApp(layout) {
364 |
365 | if (!layout.lib) {
366 | layout.lib = [];
367 | }
368 |
369 | if (!layout.modules) {
370 | layout.modules = {};
371 | }
372 |
373 | for (var i = 0; i < layout.lib.length; i++) {
374 | var lib;
375 | switch (layout.lib[i].type) {
376 | case 'css' :
377 | lib = document.createElement('link');
378 | lib.setAttribute('href', layout.lib[i].path);
379 | lib.setAttribute('rel', 'stylesheet');
380 | dataStore.CSS[layout.lib[i].path] = lib.outerHTML;
381 | break;
382 | case 'js':
383 | lib = document.createElement('script');
384 | lib.setAttribute('async', true);
385 | lib.setAttribute('src', layout.lib[i].path);
386 | dataStore.JS[layout.lib[i].path] = lib.outerHTML;
387 | break;
388 | }
389 | document.head.appendChild(lib);
390 | }
391 |
392 | // building logic modules
393 | for (var j = 0; j < layout.modules.logic.length; j++) {
394 | appendDOMNode(
395 | createModuleElement(layout.modules.logic[j], 'false', 'false')
396 | );
397 | }
398 |
399 | // check if dataStore compiled is set, if not try to retrieve it from the html element
400 | dataStore.compiled = document.querySelector('html').classList.contains('compiled-app');
401 | if(dataStore.compiled) {
402 | return;
403 | }
404 |
405 | var fullList = {};
406 | var screenList = Object.keys(layout.modules.ui);
407 | for (var k = 0; k < screenList.length; k++) {
408 | var screenModules = Object.keys( layout.modules.ui[screenList[k]] );
409 | for (var l = 0; l < screenModules.length; l++) {
410 | fullList[screenModules[l]] = true;
411 | }
412 | }
413 |
414 | var layoutModules = Object.keys(fullList);
415 | for (var n = 0; n < layoutModules.length; n++) {
416 | var tempNewModule = createModuleElement( layoutModules[n] );
417 | appendDOMNode(tempNewModule);
418 | }
419 | }
420 |
421 | /**
422 | * method to create html module element
423 | *
424 | * @memberOf app
425 | * @function createModuleElement
426 | * @param {string} name modurle name
427 | * @param {string} html html for the module
428 | * @param {string} css css file
429 | * @returns {app_L14.createModuleElement.newModule|Element}
430 | */
431 | function createModuleElement(name, html, css) {
432 | var newModule = document.createElement('div');
433 | if(!html) {
434 | html='true';
435 | }
436 | if(!css) {
437 | css='true';
438 | }
439 | newModule.id=name+'-module';
440 | newModule.classList.add(
441 | 'appModule',
442 | 'hidden',
443 | name+'-module'
444 | );
445 |
446 | newModule.setAttribute(
447 | 'data-dompath',
448 | 'body'
449 | );
450 | newModule.setAttribute(
451 | 'data-moduletype',
452 | name
453 | );
454 | newModule.setAttribute(
455 | 'data-html',
456 | html
457 | );
458 | newModule.setAttribute(
459 | 'data-css',
460 | css
461 | );
462 |
463 | return newModule;
464 | }
465 |
466 | /**
467 | * @memberOf app
468 | * @param {string} moduleType
469 | * @returns {Boolean}
470 | */
471 | function checkModuleExists(moduleType){
472 | return !!!constructors[moduleType];
473 | }
474 |
475 | /**
476 | * @memberOf app
477 | * @param {object} parent
478 | * @returns {void}
479 | */
480 | function findAndInitDynamicModules(parent){
481 | buildModules(parent.querySelectorAll('[data-moduletype]'));
482 | }
483 |
484 | /**
485 | * @memberOf app
486 | * @function addConstructor
487 | * @param {string} type
488 | * @param {function} moduleInit
489 | * @returns {void}
490 | */
491 | function addConstructor(type, moduleInit){
492 | if(constructors[type]) {
493 | return;
494 | }
495 |
496 | constructors[type] = moduleInit;
497 | if(document.readyState == 'complete') {
498 | deferredLoad(type);
499 | }
500 | }
501 |
502 | /**
503 | * @memberOf app
504 | * @function initModules
505 | * @returns {void}
506 | */
507 | function initModules(){
508 | switch(document.readyState){
509 | case 'interactive' :
510 | //dom not yet ready
511 | break;
512 | case 'complete' :
513 | getModules();
514 | buildModules();
515 | break;
516 | }
517 | }
518 |
519 | /************\
520 | Utils
521 | \************/
522 |
523 | /*
524 | * @memberOf app
525 | * @function fillTemplate
526 | * @param {string} id of element to fetch innerHTML as contents for template or raw string to be used as template if rawString set to true
527 | * @param {object} values should contain the key value pairs for all template Data
528 | * @param {bool} rawString use id as a raw html string
529 | * @param {bool} asString return as string or not
530 | * @returns {DomElement|string} if asString is false or not specified will return Filled out Template Element, if asString is true will return a filled out template string
531 | */
532 | function fillTemplate(id, values, rawString, asString) {
533 | var template = id;
534 |
535 | if (!id) {
536 | throw new AppError('Templates must specify either id or a string+rawString flag', 'app.template');
537 | }
538 | if(!rawString) {
539 | template=document.getElementById(id).innerHTML;
540 | }
541 |
542 | var keys=Object.keys(values);
543 | for(var i=0; i';
574 |
575 | if (type === 'test') {
576 | defaults += '' +
577 | '' +
578 | '' +
579 | '' +
580 | '';
581 | }
582 |
583 | this.body='';
584 | this.head='';
585 | var list=[
586 | 'HTML',
587 | 'CSS',
588 | 'JS'
589 | ];
590 |
591 | /**
592 | * compile module
593 | * @param {string} name
594 | * @param {string} content
595 | * @returns {void}
596 | */
597 | function compileModule(name, content){
598 |
599 | var module=createModuleElement(name);
600 | module.innerHTML=content;
601 | this.body+=module.outerHTML;
602 | }
603 |
604 | for(var j=0; j