Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Flowfeeds
Search
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
Oxlintはいいぞ(続)
yug1224
1
500
楽しそうなつよつよエンジニアと目が死んでる僕/A brilliant engineer having a blast, and dead-eyed me.
3l4l5
2
270
tsc.rip を支える技術 / Kyoto.なんか #8
susisu
0
4.1k
Hono + Inertia + React で LP を構築した話
oukayuka
2
190
FastAPI の並行処理モデルを完全に理解する
hoto17296
9
3.3k
プロポーザルを書いてもらう
pvcresin
0
590
Pythonの実行はどこまで賢くなったのか? CPythonとPyPyから見る最適化のしくみ
curekoshimizu
4
2.3k
ソフトウェアラスタライザ
fadis
1
750
ALB ログから Trace を気合で繋げる技術
fohte
7
820
初めての模倣学習とVLA
natsutan
0
370
KotlinConf Extended South Korea 2026 Keynote
l2hyunwoo
0
130
Claude Code全社展開のためにやったことn選~プラグイン302個・コミッター271人を支えるために~
kenchan
5
1.8k
Featured
See All Featured
KATA
mclloyd
PRO
35
15k
Taking LLMs out of the black box: A practical guide to human-in-the-loop distillation
inesmontani
PRO
3
2.4k
Bootstrapping a Software Product
garrettdimon
PRO
306
120k
The AI Revolution Will Not Be Monopolized: How open-source beats economies of scale, even for LLMs
inesmontani
PRO
3
3.7k
SEO for Brand Visibility & Recognition
aleyda
0
4.7k
Mind Mapping
helmedeiros
PRO
1
340
Large-scale JavaScript Application Architecture
addyosmani
515
110k
Evolution of real-time – Irina Nazarova, EuRuKo, 2024
irinanazarova
9
1.5k
Context Engineering - Making Every Token Count
addyosmani
9
1.1k
The Curious Case for Waylosing
cassininazir
1
490
Refactoring Trust on Your Teams (GOTO; Chicago 2020)
rmw
35
3.8k
Intergalactic Javascript Robots from Outer Space
tanoku
273
27k
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