Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Flowfeeds
Search
Sponsored
·
SiteGround - Reliable hosting with speed, security, and support you can count on.
→
Benjamin Rhodes
May 22, 2013
Programming
5.9k
6
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Flowfeeds
Presentation about flowfeeds.com for the southern California ember.js group.
Benjamin Rhodes
May 22, 2013
Other Decks in Programming
See All in Programming
setup-vp GitLab対応の裏側
naokihaba
0
160
HTML-in-Canvasで作る未来のWeb UI表現
clockmaker
4
4.6k
外から家のPCの電源入れたい!をPHPで解決する
kawashimo0
1
130
Kubernetes祭り #2 OP/ED
bells17
0
110
技術的負債の返済は、AI時代の複利で効く投資 — 経営としての意思決定とその遂行
curekoshimizu
1
2.3k
コードで差別化できない時代の ソフトウェアエンジニアリング / Software Engineering in an Era Where Code Doesn’t Differentiate
kishida
2
160
気持ちぃ〜角丸 Squircle
ryu1013
0
280
半永久的に提供し続けられるプライベートクラウドを目指して ― 利用者の認知負荷を抑えるAPI抽象化とハードウェア世代交代の基盤設計
tomokon
0
480
設計次第でAIコードの読む量は減らせる / designing-for-code-reading
minodriven
34
16k
速習iPhone Duo対応
yuukiw00w
2
980
機械に任せるテスト、人が見るテスト ⽣成AIで引き直した、運⽤保守フェーズの線引き
dske104
0
180
RAG の “R” を Swift で覗いてみる 〜「意味から探す」検索の仕組み〜
nao_randd
0
140
Featured
See All Featured
We Are The Robots
honzajavorek
0
390
Java REST API Framework Comparison - PWX 2021
mraible
34
9.8k
Avoiding the “Bad Training, Faster” Trap in the Age of AI
tmiket
0
270
From π to Pie charts
rasagy
1
400
How to Build an AI Search Optimization Roadmap - Criteria and Steps to Take #SEOIRL
aleyda
1
2.2k
10 Git Anti Patterns You Should be Aware of
lemiorhan
PRO
659
62k
Exploring the relationship between traditional SERPs and Gen AI search
raygrieselhuber
PRO
4
4.3k
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.8k
Leadership Guide Workshop - DevTernity 2021
reverentgeek
1
390
The Success of Rails: Ensuring Growth for the Next 100 Years
eileencodes
47
8.4k
The Cult of Friendly URLs
andyhume
79
7k
Visualization
eitanlees
153
17k
Transcript
Wednesday, May 22, 13
Wednesday, May 22, 13
Why? • To Many RSS feeds :( • Video Playlists
• New music everyday Wednesday, May 22, 13
flowfeeds.com • Stack • Ember.js & Rails 4 • Features
• Audio & Video Player • Drag & Drop Sorting • Infinite Scroll Wednesday, May 22, 13
Audio & Video • Libraries • Video: YouTube JS API
• Audio: SoundManager2 Wednesday, May 22, 13
Flowfeeds.PlayableController = Ember.ObjectController.extend({ bytesLoaded: 0, bytesTotal: 0, duration: 0, isPlaying:
false, position: 0, setup: Ember.K, play: Ember.K, pause: Ember.K, jump: Ember.K, stop: Ember.K }); Wednesday, May 22, 13
Flowfeeds.VideoController = Flowfeeds.PlayableController.extend({ setup: function(model) { this.set('content', model); this.setupAndPlayVideo(); },
// implementation details }); Flowfeeds.AudioController = Flowfeeds.PlayableController.extend({ setup: function(model) { this.set('content', model); this.setupAndPlayAudio(); }, // implementation details }); Wednesday, May 22, 13
PlayerView Wednesday, May 22, 13
Model Attributes {{ artist.name }} {{ title }} <img {{
bindAttr src="thumb" }} /> Wednesday, May 22, 13
Time {{ formatTime position }} {{ formatTime duration }} Wednesday,
May 22, 13
Ember.Handlebars.registerBoundHelper('formatTime', function(ms) { var x = ms / 1000, seconds
= x % 60 >> 0, minutes = x / 60 % 60 >> 0, hours = x / 3600 % 60 >> 0; if(seconds < 10) seconds = "0" + seconds; if(minutes < 10) minutes = "0" + minutes; if(hours === 0) { hours = ""; } else { hours = hours + ":"; } return hours + minutes + ":" + seconds; }); Wednesday, May 22, 13
ProgressView {{ render 'progress' controller }} Wednesday, May 22, 13
progess.hbs <div class="bar loading" {{bindAttr style="view.loadingBarStyle"}}> <div class="bar progress" {{bindAttr
style="view.progressBarStyle"}}> Wednesday, May 22, 13
Flowfeeds.ProgressView = Ember.View.extend({ progressBarStyle: function() { return 'width: ' +
this.get('controller.percentComplete') + '%;'; }.property('controller.percentComplete'), loadingBarStyle: function() { return 'width: ' + this.get('controller.percentLoaded') + '%;'; }.property('controller.percentLoaded'), Wednesday, May 22, 13
Flowfeeds.ProgressController = Ember.ObjectController.extend percentComplete: function() { var duration = this.get('duration');
if(duration === 0) return 0; return 100 * (this.get('position') / duration); }.property('position', 'duration'), percentLoaded: function() { var total = this.get('bytesTotal'); if(total === 0) return 0; return 100 * (this.get('bytesLoaded') / total); }.property('bytesLoaded', 'bytesTotal') }); Wednesday, May 22, 13
Flowfeeds.ProgressView = Ember.View.extend({ click: function(event) { this.jumpEvent(event); }, jumpEvent: function(event)
{ var pos = this.getX(event) / this.$().width(); this.get('controller').send('jump', pos); }, getX: function(event) { return event.pageX - $(event.currentTarget).offset().left; }, Wednesday, May 22, 13
mouseDown: function(event) { event.preventDefault(); this.scrubbing = true; }, mouseMove: function(event)
{ if(this.scrubbing) this.jumpEvent(event); }, mouseUp: function() { this.scrubbing = false; }, mouseLeave: function() { this.scrubbing = false; }, Wednesday, May 22, 13
Play / Next / Prev <button {{action next}}> Wednesday, May
22, 13
Flowfeeds.ApplicationRoute = Ember.Route.extend({ events: { play: function(playable, controller) { this.skipable
= controller.get('target'); this.controllerFor('player').play(playable); }, previous: function() { if(this.skipable) this.skipable.send('previous'); }, next: function() { if(this.skipable) this.skipable.send('next'); }, Wednesday, May 22, 13
Wednesday, May 22, 13
Sortable Wednesday, May 22, 13
Sortable • Libraries: • jQuery UI Sortable Wednesday, May 22,
13
<div class="playables"> {{#each controller}} <div class="playable" {{bindAttr data-id="id"}}> </div> {{/each}}
</div> Wednesday, May 22, 13
Flowfeeds.SortablePlaylistView = Ember.View.extend({ didInsertElement: function() { var controller = this.get('controller');
$('.playables').sortable({ update: function(event, ui) { var indexes = {}; $(this).find('.playable').each(function(index) { indexes[$(this).data('id').toString()] = index; }); $(this).sortable('cancel'); controller.updateSortOrder(indexes); } }); } }); Wednesday, May 22, 13
FlowFeeds.ItemsController = Ember.ArrayController.extend({ sortProperties: ['idx'], updateSortOrder: function(indexes) { this.forEach(function(item) {
var index = indexes[item.get('id')]; item.set('idx', index); }); } }); Wednesday, May 22, 13
Infinite Scroll Wednesday, May 22, 13
{{#view Flowfeeds.InfiniteScrollView}} {{ render 'videos' model }} {{/view}} Wednesday, May
22, 13
Flowfeeds.InfiniteScrollView = Ember.View.extend({ elementId: 'infinite', layout: Ember.Handlebars.compile( "{{ yield }}{{
partial loader }}" ), didInsertElement: function() { var view = this; $('#main').on('scroll', function(){ if(view.isScrolledToBottom()) view.get('controller').send('more'); }); }, willDestroyElement: function() { $('#main').off('scroll'); } }); Wednesday, May 22, 13
Flowfeeds.FeedRoute = Ember.Route.extend({ events: { more: function() { this.modelFor('feed').loadNextPageOfTracks(); }
} }); Wednesday, May 22, 13
Overview • Inheritance • Helpers • Sliders • Sortable •
Infinite Scroll Wednesday, May 22, 13
Questions? • Source: • github.com/nerdyworm/flowfeeds • Contact •
[email protected]
Wednesday,
May 22, 13