Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Firehose #6

Merged
merged 25 commits into from Nov 21, 2015
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
25 commits
Select commit Hold shift + click to select a range
6f6c4bf
Firehose model.
bryanveloso Nov 15, 2015
fd600eb
Strap the firehose to Firebase.
bryanveloso Nov 15, 2015
c869336
Convert the test from .coffee back to .js.
bryanveloso Nov 15, 2015
359db13
Having to rename firehose to event because of Emberfire's pluralizing…
bryanveloso Nov 16, 2015
87cc6da
Yay it works kinda.
bryanveloso Nov 16, 2015
ae3ec2d
One more name thing.
bryanveloso Nov 16, 2015
cd58fec
Working on the ticker first. :3
bryanveloso Nov 16, 2015
1d2365c
Get the event ticker styles started.
bryanveloso Nov 16, 2015
921b91c
Ticker stylings and such.
bryanveloso Nov 16, 2015
6cf784f
inline-flex!
bryanveloso Nov 16, 2015
f805c2a
Some style testing.
bryanveloso Nov 17, 2015
7c0977b
Proxy against the live site so we don't have to run Django locally.
bryanveloso Nov 18, 2015
1f806e6
Add the concept of an event-ticker component.
bryanveloso Nov 19, 2015
f1ff65b
The child of event-ticker...
bryanveloso Nov 19, 2015
ea89e34
I fucking love Flexbox.
bryanveloso Nov 19, 2015
44bc435
Use the new components. :D
bryanveloso Nov 19, 2015
528ecf2
Change "donation" to "tip."
bryanveloso Nov 20, 2015
575e95a
Style tips and all that jazz.
bryanveloso Nov 20, 2015
b6f5992
Some mods.
bryanveloso Nov 20, 2015
fe15bd7
Progress on getting messages to fade in and out.
bryanveloso Nov 21, 2015
aeaf3bf
More tweaks.
bryanveloso Nov 21, 2015
d31d7a2
Implement the toggling of the ticker list.
bryanveloso Nov 21, 2015
8c12197
We got a timer working! Woo! :D
bryanveloso Nov 21, 2015
a83f9d0
Tweaks.
bryanveloso Nov 21, 2015
86c5f68
That's better.
bryanveloso Nov 21, 2015
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
2 changes: 1 addition & 1 deletion .ember-cli
@@ -1,6 +1,6 @@
{
"port": 4200,
"proxy": "http://localhost:8000",
"proxy": "http://avalonstar.tv",

/**
Ember CLI sends analytics information by default. The data is completely
Expand Down
8 changes: 8 additions & 0 deletions app/adapters/event.js
@@ -0,0 +1,8 @@
import Ember from 'ember';
import FirebaseAdapter from 'emberfire/adapters/firebase';

const { inject } = Ember;

export default FirebaseAdapter.extend({
firebase: inject.service()
});
35 changes: 35 additions & 0 deletions app/components/event-ticker-item.js
@@ -0,0 +1,35 @@
import Ember from 'ember';

export default Ember.Component.extend({
classNames: ['ticker-item', 'ticker-item--hidden'],
// classNames: ['ticker-item'],
tagName: ['li'],

// Attribute Bindings
attributeBindings: ['type:data-event'],
type: Ember.computed.alias('event.event'),

didInsertElement() {
// A new event here should reset the idle timer of the parent.
this.get('parentView').send('resetTimer');

//
this.$().removeClass('ticker-item--hidden');

// Store the width of the element in a `data-width` attribute.
this.$().attr('data-width', this.$().width());

// If there's a tip, mark it as visible for 10 seconds.
let tickerMessage = this.$('.ticker__message');
let toggleClass = 'ticker__message--hidden';

tickerMessage.removeClass(toggleClass);
Ember.run.later((function() {
tickerMessage.addClass(toggleClass);
}), 5000);
},

eventIsTip: function() {
return this.get('event.event') === 'tip';
}.property('person')
});
41 changes: 41 additions & 0 deletions app/components/event-ticker.js
@@ -0,0 +1,41 @@
import Ember from 'ember';

export default Ember.Component.extend(Ember.PromiseProxyMixin, {
classNameBindings: ['isHidden:ticker-list--hidden'],
classNames: ['ticker-list'],
tagName: ['ol'],

init() {
this._super();
let promise = this.get('store').query('event', {
orderBy: 'timestamp',
});
if (promise) {
return this.set('promise', promise);
}
},

// Logic related to the toggling of the ticker list. `delay` is used to run
// a timer that is destroyed and recreated every time a new event is added.
isHidden: true, // Is the ticker currently hidden?
delay: 1000 * 60 * 5, // 5 minutes.

_timerExpired() {
this.set('isHidden', true);
},
setupTimer() {
this._timer = Ember.run.later(this, this._timerExpired, this.get('delay'));
this.set('isHidden', false);
},
removeTimer() {
Ember.run.cancel(this._timer);
delete this._timer;
},

actions: {
resetTimer() {
this.removeTimer();
this.setupTimer();
}
}
});
13 changes: 13 additions & 0 deletions app/models/event.js
@@ -0,0 +1,13 @@
import DS from 'ember-data';

export default DS.Model.extend({
event: DS.attr('string'),
username: DS.attr('string'),

// Substreak specific.
length: DS.attr('number'),

// Tip specific.
message: DS.attr('string'),
amount: DS.attr('string')
});
4 changes: 3 additions & 1 deletion app/router.js
Expand Up @@ -12,8 +12,10 @@ Router.map(function() {
// Overlays.
this.route('discussion', {path: 'overlay/discussion'});
this.route('gaming', {path: 'overlay/gaming'});
this.route('notifier', {path: 'overlay/notifier'});
this.route('prologue', {path: 'overlay/prologue'});

this.route('ticker', {path: 'overlay/ticker'});
this.route('notifier', {path: 'overlay/notifier'});
});

export default Router;
1 change: 1 addition & 0 deletions app/routes/gaming.coffee
Expand Up @@ -8,5 +8,6 @@ GamingRoute = Ember.Route.extend
hosts: @store.findAll 'host'
raids: @store.findAll('raid').then (items) ->
items.get('firstObject')
firehose: @store.findAll('event')

`export default GamingRoute`
7 changes: 7 additions & 0 deletions app/routes/ticker.js
@@ -0,0 +1,7 @@
import Ember from 'ember';

export default Ember.Route.extend({
model() {
return this.store.findAll('event');
}
});
1 change: 1 addition & 0 deletions app/styles/app.scss
Expand Up @@ -6,6 +6,7 @@
// Components.
@import "components/chat-message";
@import "components/event-notifier";
@import "components/event-ticker";
@import "components/broadcast-informer";

// Routes.
Expand Down
4 changes: 2 additions & 2 deletions app/styles/components/_event-notifier.scss
Expand Up @@ -130,8 +130,8 @@
// Event-based state changes.
.notifier__container {
&[data-type="donation"] {
.event-timer { background-color: $event-donation; }
.event__type { color: $event-donation; }
.event-timer { background-color: $event-tip; }
.event__type { color: $event-tip; }
}
&[data-type="host"] {
.event-timer { background-color: $event-host; }
Expand Down
131 changes: 131 additions & 0 deletions app/styles/components/_event-ticker.scss
@@ -0,0 +1,131 @@
.event-ticker {
display: flex; align-items: flex-end;
width: 1280px; height: 240px;

color: white;
font-family: "Gotham SSm A", "Gotham SSm B";
}

.ticker-list {
display: flex; flex-direction: row-reverse; justify-content: flex-end;
position: relative; bottom: 0;

background-color: #1f1f1f;
white-space: nowrap;

transition: all 500ms ease;
}
.ticker-list--hidden {
bottom: -26px;
opacity: 0.0;
}

// .ticker-item serves as the container to the current event, as it's width
// is assigned as `data-width` upon instantiation.
.ticker-item {
flex: none;
position: relative;
margin: 0 1px;

transition: all 500ms ease;

// box-shadow: 0 1px 3px rgba(0,0,0,0.12), 0 1px 2px rgba(0,0,0,0.24);

/*
&:before {
// Circle.
content: '';
position: absolute; bottom: -8px; left: 0;

width: 6px; height: 6px;
border-radius: 50%;
background-color: #000;
}
&:after {
// Timeline.
content: '';
position: absolute; right: 4px; bottom: -6px; left: 10px;

height: 1px;
background-color: #000;
}
*/
}

.ticker-item--hidden {
.ticker-wrapper { opacity: 0.0; width: 1px; }
}

// .ticket-wrapper is animatable.
.ticker-wrapper {
display: inline-flex;
width: 100%;
padding: 0 8px;

background-color: #1f1f1f;
border-bottom: 2px solid white;
}

.ticker__piece {
}
.ticker__type {
font-size: 14px;
text-transform: uppercase;
padding: 6px 0px 6px;
}
.ticker__actor {
font-weight: 500;
font-size: 14px;
padding: 6px 8px;
padding-right: 0px;
}

.ticker__message {
position: absolute; bottom: 46px; left: 0;
width: 110%;
padding: 12px;

background: #1f1f1f;
color: #fff;
font-size: 14px;
line-height: 18px;
white-space: normal;

// box-shadow: 0 5px 5px 0 rgba(0,0,0,0.1), 0 2px 3px 0 rgba(0,0,0,0.2);

transition: 500ms all ease;

&:after {
content: '';
position: absolute; bottom: -10px; left: 0;
width: 0;
height: 0;
border-style: solid;
border-width: 10px 10px 0 0;
border-color: #1f1f1f transparent transparent transparent;
}
}

.ticker__message--hidden {
bottom: 56px;
opacity: 0.0;
}

// Event type customization.
$events:
(host $event-host)
(raid $event-raid)
(subscription $event-subscription)
(substreak $event-substreak)
(tip $event-tip);
@each $e in $events {
[data-event="#{nth($e, 1)}"] {
.ticker-wrapper { border-color: nth($e, 2); }
.ticker__type { color: nth($e, 2); }
}
}

[data-event="follow"] {
.ticker-wrapper { border-color: #000; }
.ticker__type { color: #666; }
}
3 changes: 1 addition & 2 deletions app/styles/routes/_gaming.scss
Expand Up @@ -13,8 +13,7 @@
.overlay--main {
// background-image: url('http://s3-ap-southeast-2.amazonaws.com/ag.images/Thumbnails/Articles/MegaMan/MegaMan3Image.jpg')
// background-image: url('http://i.kinja-img.com/gawker-media/image/upload/isyb6kcwv6h5yth7xelb.jpg');
background-image: url('http://i.ytimg.com/vi/8vc655oD3i8/maxresdefault.jpg');

// background-image: url('http://i.ytimg.com/vi/8vc655oD3i8/maxresdefault.jpg');
}

.overlay--game {
Expand Down
2 changes: 1 addition & 1 deletion app/styles/structure/_color.scss
@@ -1,4 +1,4 @@
$event-donation: #2ecc71;
$event-tip: #2ecc71;
$event-host: #9b59b6;
$event-subscription: #3498db;
$event-resubscription: #3498db;
Expand Down
10 changes: 10 additions & 0 deletions app/templates/components/event-ticker-item.hbs
@@ -0,0 +1,10 @@
<div class="ticker-wrapper">
{{#if eventIsTip}}
<span class="ticker__piece ticker__type"><strong>${{event.amount}}</strong> {{event.event}}</span>
<span class="ticker__piece ticker__actor">{{event.username}}</span>
<div class="ticker__message ticker__message--hidden">{{event.message}}</div>
{{else}}
<span class="ticker__piece ticker__type">{{event.event}}{{#if event.length}} x{{event.length}}{{/if}}</span>
<span class="ticker__piece ticker__actor">{{event.username}}</span>
{{/if}}
</div>
7 changes: 7 additions & 0 deletions app/templates/components/event-ticker.hbs
@@ -0,0 +1,7 @@
{{#if isPending}}
{{!-- Work on a pending state... not that we need one. --}}
{{else}}
{{#each promise._result as |event|}}
{{event-ticker-item event=event}}
{{/each}}
{{/if}}
3 changes: 3 additions & 0 deletions app/templates/ticker.hbs
@@ -0,0 +1,3 @@
<div class="event-ticker">
{{event-ticker store=store}}
</div>
26 changes: 26 additions & 0 deletions tests/integration/components/event-ticker-item-test.js
@@ -0,0 +1,26 @@
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';

moduleForComponent('event-ticker-item', 'Integration | Component | event ticker', {
integration: true
});

test('it renders', function(assert) {
assert.expect(2);

// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.on('myAction', function(val) { ... });

this.render(hbs`{{event-ticker-item}}`);

assert.equal(this.$().text().trim(), '');

// Template block usage:
this.render(hbs`
{{#event-ticker-item}}
template block text
{{/event-ticker-item}}
`);

assert.equal(this.$().text().trim(), 'template block text');
});
26 changes: 26 additions & 0 deletions tests/integration/components/event-ticker-test.js
@@ -0,0 +1,26 @@
import { moduleForComponent, test } from 'ember-qunit';
import hbs from 'htmlbars-inline-precompile';

moduleForComponent('event-ticker', 'Integration | Component | event ticker', {
integration: true
});

test('it renders', function(assert) {
assert.expect(2);

// Set any properties with this.set('myProperty', 'value');
// Handle any actions with this.on('myAction', function(val) { ... });

this.render(hbs`{{event-ticker}}`);

assert.equal(this.$().text().trim(), '');

// Template block usage:
this.render(hbs`
{{#event-ticker}}
template block text
{{/event-ticker}}
`);

assert.equal(this.$().text().trim(), 'template block text');
});
12 changes: 12 additions & 0 deletions tests/unit/models/event-test.js
@@ -0,0 +1,12 @@
import { moduleForModel, test } from 'ember-qunit';

moduleForModel('event', 'Unit | Model | event', {
// Specify the other units that are required for this test.
needs: []
});

test('it exists', function(assert) {
var model = this.subject();
// var store = this.store();
assert.ok(!!model);
});