-
Notifications
You must be signed in to change notification settings - Fork 0
/
songlocator-backbone.coffee
113 lines (89 loc) · 3.18 KB
/
songlocator-backbone.coffee
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
###
SongLocator for Backbone.
2013 (c) Andrey Popp <[email protected]>
###
((root, factory) ->
if typeof exports == 'object'
_ = require 'underscore'
Backbone = require 'backbone'
module.exports = factory(_, Backbone, require)
else if typeof define == 'function' and define.amd
define (require) ->
_ = require 'underscore'
Backbone = require 'backbone'
root.Backbone.SongLocator = factory(_, Backbone, require)
else
root.Backbone.SongLocator = factory(root._, root.Backbone)
) this, (_, Backbone, require) ->
{Collection, Model} = Backbone
{uniqueId, extend} = _
class Stream extends Model
class Song extends Model
equals: (other) ->
tTitle = (this.get('title') or '').toLowerCase()
tArtist = (this.get('artist') or '').toLowerCase()
oTitle = (other.get('title') or '').toLowerCase()
oArtist = (other.get('artist') or '').toLowerCase()
tTitle == oTitle and tArtist == oArtist
constructor: (attributes, options) ->
super
this.qid = undefined
this.streams = this.get('streams') or new Collection()
if not (this.streams instanceof Collection)
this.streams = new Collection(this.streams)
this.set('streams', this.streams)
this.listenTo this.streams, 'change add remove destroy sort reset', =>
this.trigger 'change:streams', this, this.streams, {}
this.trigger 'change', this, {}
if options?.resolver?
this.resolver = options.resolver
this.listenTo this.resolver, 'results', (r) =>
return unless r.qid == this.qid
for stream in r.results
stream = new Stream(stream)
continue unless this.equals(stream)
this.streams.add(stream)
resolve: ->
this.qid = uniqueId('resolveQID')
this.resolver.resolve(this.qid, this.get('title'), this.get('artist'))
class Songs extends Collection
model: Song
songForStream: (stream) ->
this.find (song) =>
song.equals(stream)
createSong: (stream) ->
new Song
title: stream.get('title')
artist: stream.get('artist')
streams: [stream]
addStream: (stream) ->
if not (stream instanceof Stream)
stream = new Stream(stream)
song = this.songForStream(stream)
if song
streams = song.streams.where(source: stream.source)
song.streams.add(stream) if streams.length == 0
else
song = this.createSong(stream)
this.add(song)
class ResolvedSongs extends Songs
constructor: (resolver, songs, options) ->
super(songs, options)
this.resolver = resolver
this.qid = undefined
this.listenTo this.resolver, 'results', (r) =>
return unless r.qid == this.qid
this.addStream(stream) for stream in r.results
createSong: (stream) ->
new Song {
title: stream.get('title')
artist: stream.get('artist')
streams: [stream]
}, {resolver: this.resolver}
search: (query) ->
query = (query or '').trim()
return unless query
this.qid = uniqueId('searchQID')
this.resolver.search(this.qid, query)
this.reset()
{Song, Stream, Songs, ResolvedSongs}