diff --git a/dss/settings.py b/dss/settings.py index fd3d605..c2037bd 100644 --- a/dss/settings.py +++ b/dss/settings.py @@ -141,7 +141,7 @@ MIDDLEWARE_CLASSES = ( 'django.middleware.clickjacking.XFrameOptionsMiddleware', 'spa.middleware.uploadify.SWFUploadMiddleware', #'spa.middleware.sqlprinter.SqlPrintingMiddleware' if DEBUG else None, - 'debug_toolbar.middleware.DebugToolbarMiddleware', + #'debug_toolbar.middleware.DebugToolbarMiddleware', ) WSGI_APPLICATION = 'dss.wsgi.application' diff --git a/spa/models/activity.py b/spa/models/activity.py index 92ff297..0cdcbfc 100644 --- a/spa/models/activity.py +++ b/spa/models/activity.py @@ -30,7 +30,7 @@ class ActivityMix(Activity): return self.mix.title def get_object_url(self): - return self.mix.get_full_url() + return self.mix.get_absolute_url() def get_object_singular(self): return "mix" @@ -42,7 +42,7 @@ class ActivityFavourite(Activity): return self.mix.title def get_object_url(self): - return self.mix.get_full_url() + return self.mix.get_absolute_url() def get_object_singular(self): return "mix" @@ -57,7 +57,7 @@ class ActivityPlay(Activity): return self.mix.title def get_object_url(self): - return self.mix.get_full_url() + return self.mix.get_absolute_url() def get_object_singular(self): return "mix" @@ -73,7 +73,7 @@ class ActivityLike(Activity): return self.mix.title def get_object_url(self): - return self.mix.get_full_url() + return self.mix.get_absolute_url() def get_object_singular(self): return "mix" @@ -89,7 +89,7 @@ class ActivityDownload(Activity): return self.mix.title def get_object_url(self): - return self.mix.get_full_url() + return self.mix.get_absolute_url() def get_object_singular(self): return "mix" diff --git a/static/css/deepsouthsounds.css b/static/css/deepsouthsounds.css index 5879cd4..606c859 100644 --- a/static/css/deepsouthsounds.css +++ b/static/css/deepsouthsounds.css @@ -16,6 +16,7 @@ body { padding-top: 45px; padding-bottom: 40px; padding-right: 32px; + background: url('../img/bg.gif'); } /* IE/Chrome image fix */ @@ -426,4 +427,57 @@ div.event-content td { to { background-position: -50px 0; } +} + +.now-playing-image { + width: 32px; + height: 32px; +} + +.accessible-description { + display: none !important; +} + +.player-button { + width: 32px; + height: 32px; + background: url(../img/player-sprite.png); + cursor: pointer; + color: #f77f00; + text-decoration: none; + display: inline-block; +} + +.now-playing-play { + background-position: -90px 0px; +} +.now-playing-pause{ + background-position: -210px 0px; +} +.now-playing-bio p { + display: inline-block; + margin-left: 5px; +} + +#aaaa{ + border: 1px solid #802c59; + + -webkit-border-radius: 15px; + -moz-border-radius: 15px; + border-radius: 15px; +} + +.now-playing-image-container { + display: inline-block; +} + +#sidebar-top-content { + margin-bottom: 12px; + padding: 8px; +} + +.div-small-heading{ + width: 98%; + text-align: center; + margin-bottom: 8px; } \ No newline at end of file diff --git a/static/css/testing.css b/static/css/testing.css new file mode 100644 index 0000000..41b0087 --- /dev/null +++ b/static/css/testing.css @@ -0,0 +1,1043 @@ +html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6, p, blockquote, pre, a, abbr, acronym, address, big, cite, code, del, dfn, em, img, ins, kbd, q, s, samp, small, strike, strong, sub, sup, tt, var, b, u, i, center, dl, dt, dd, ol, ul, li, fieldset, form, label, legend, table, caption, tbody, tfoot, thead, tr, th, td, article, aside, canvas, details, embed, figure, figcaption, footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font-size: 100%; + font: inherit; + vertical-align: baseline +} + +article, aside, details, figcaption, figure, footer, header, hgroup, menu, nav, section { + display: block +} + +body { + line-height: 1 +} + +ol, ul { + list-style: none +} + +blockquote, q { + quotes: none +} + +blockquote:before, blockquote:after, q:before, q:after { + content: ''; + content: none +} + +table { + border-collapse: collapse; + border-spacing: 0 +} + +body { + margin: 0; + padding: 0 +} + +.container { + max-width: 920px; + padding: 0 20px; + margin: 0 auto +} + +.clear { + clear: both +} + +@font-face { + font-family: 'Copse'; + font-style: normal; + font-weight: 400; + src: local('Copse'), url(http://themes.googleusercontent.com/static/fonts/copse/v3/GTNBLj58pwv6qyDO1RGnXaCWcynf_cDxXwCLxiixG1c.woff) format('woff') +} + +body { + font-family: 'Copse'; + font-size: 16px; + line-height: 22px; + color: #373737; + -moz-font-smoothing: antialiased; + font-smoothing: antialiased; + -webkit-font-smoothing: antialiased; + text-shadow: 1px 1px 1px rgba(0, 0, 0, 0.004) +} + +hgroup { + margin-bottom: 15px +} + +hgroup h2 { + margin-bottom: 10px +} + +h2 { + font-size: 36px; + font-style: italic +} + +h3 { + font-size: 30px; + font-style: italic +} + +a { + color: inherit; + text-decoration: none +} + +.italic { + font-style: italic +} + +.bold { + font-weight: bold +} + +.grey { + color: #9b9b9b +} + +.underline a, a.underline { + border-bottom: 2px solid; + padding-bottom: 3px; + position: relative +} + +.underline a span, a.underline span { + position: absolute; + right: -23px; + font-size: 16px; + bottom: -12px; + padding: 0px 3px; + background-color: #fff +} + +.underline-yellow a, a.underline-yellow { + border-color: #f1e52f +} + +.underline-green a, a.underline-green { + border-color: #63a544 +} + +.underline-blue a, a.underline-blue { + border-color: #26acec +} + +.underline-purple a, a.underline-purple { + border-color: #3b5998 +} + +.underline-orange a, a.underline-orange { + border-color: #f60 +} + +img { + max-width: 100% +} + +hr { + border: none; + color: #9b9b9b; + background-color: #9b9b9b; + height: 2px +} + +input[type=text], input[type=email], input[type=url] { + background-color: #dedede; + width: 205px; + padding: 8px 5px; + border-top: none; + border-left: none; + border-right: none; + border-bottom: 2px solid #63a544; + font-family: 'Copse'; + font-size: 12px +} + +input { + outline: none; + margin-bottom: 20px; + display: block; + font-family: 'Copse' +} + +input[type=text]:focus, input[type=email]:focus { + outline: none; + border-bottom: 2px solid #f1e52f +} + +input[type=submit] { + background-color: #63a544; + color: white; + font-size: 12px; + line-height: 20px; + padding: 5px 17px; + border: none; + -webkit-appearance: none; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + -moz-background-clip: padding; + -webkit-background-clip: padding-box; + background-clip: padding-box +} + +input[type=submit]:hover { + background-color: #cbd13e +} + +.button { + display: inline-block; + color: white; + font-size: 12px; + line-height: 20px; + padding: 5px 17px; + -webkit-border-radius: 5px; + -moz-border-radius: 5px; + border-radius: 5px; + -moz-background-clip: padding; + -webkit-background-clip: padding-box; + background-clip: padding-box +} + +.button:hover { + background-color: #cbd13e +} + +.green-button { + background-color: #63a544 +} + +#header { + background: url('/wp-content/themes/fivenew/img/header-background.png'); + width: 100% +} + +#header #topNav { + background-color: #171717; + -webkit-box-shadow: 0px 2px 12px rgba(0, 0, 0, 0.55); + -moz-box-shadow: 0px 2px 12px rgba(0, 0, 0, 0.55); + box-shadow: 0px 2px 12px rgba(0, 0, 0, 0.55) +} + +.modalDialog { + position: fixed; + top: 0; + right: 0; + bottom: 0; + left: 0; + background: rgba(0, 0, 0, 0.8); + z-index: 99999; + opacity: 0; + -webkit-transition: opacity 400ms ease-in; + -moz-transition: opacity 400ms ease-in; + transition: opacity 400ms ease-in; + pointer-events: none +} + +.modalDialog:target { + opacity: 1; + pointer-events: auto +} + +.modalDialog>div { + max-width: 570px; + position: relative; + margin: 10% auto +} + +.close { + background: #606061; + color: #FFF; + line-height: 25px; + position: absolute; + right: -12px; + text-align: center; + top: -10px; + width: 24px; + text-decoration: none; + font-weight: bold; + -webkit-border-radius: 12px; + -moz-border-radius: 12px; + border-radius: 12px; + -moz-box-shadow: 1px 1px 3px #000; + -webkit-box-shadow: 1px 1px 3px #000; + box-shadow: 1px 1px 3px #000 +} + +.close:hover { + background: #63a544 +} + +#openModal #newsletter form input[type=email] { + margin-right: 0; + text-align: center +} + +footer { + background-color: #171717 +} + +footer .container { + padding-top: 35px; + padding-bottom: 35px; + color: white +} + +footer .container h3 { + margin-bottom: 10px +} + +footer .container .twitter .inner .twitterInfo { + padding: 10px 0 15px; + border-bottom: 1px solid #494949; + margin-bottom: 15px +} + +footer .container .twitter .inner .twitterHandle { + color: #63a544; + display: inline-block; + margin-right: 15px +} + +footer .container .twitter .inner ul li { + margin-bottom: 20px +} + +footer .container #cats { + margin-top: 10px; + border-top: 1px solid #494949; + padding: 30px 0 +} + +footer .container #cats nav ul li { + margin-bottom: 15px +} + +footer .container #cats nav ul li a { + border-bottom: 1px solid #63a544 +} + +footer .container .copy { + border-top: 1px solid #494949; + padding: 30px 0; + font-size: 12px +} + +footer .container .copy p span { + padding: 0 5px +} + +footer .container .copy .twitter, footer .container .copy .rss, footer .container .copy .facebook { + background: url('/wp-content/themes/fivenew/img/sprite.png') no-repeat; + display: inline-block +} + +footer .container .copy .twitter { + background-position: 0px 0px; + height: 22px; + width: 23px; + margin-right: 11px +} + +footer .container .copy .rss { + background-position: 0px -64px; + width: 26px; + height: 22px +} + +footer .container .copy .facebook { + background-position: 0px -32px; + width: 17px; + height: 22px; + margin-right: 11px +} + +#about .container { + border-top: 2px solid #9b9b9b; + padding-top: 25px; + padding-bottom: 25px +} + +#about .container h3 { + margin-bottom: 15px +} + +#about .container p { + margin-bottom: 10px +} + +#archive { + padding-top: 30px +} + +.mainSection { + width: 66%; + margin-right: 10%; + float: left +} + +.mainSection h1 { + font-family: 'Copse'; + font-size: 36px; + line-height: 1em; + margin-bottom: 18px +} + +.mainSection hr { + border: none; + color: #9b9b9b; + margin: 30px 0; + background-color: #9b9b9b; + height: 1px +} + +.mainSection h1+p { + font-size: 19px; + line-height: 1.4em +} + +.mainSection p, .mainSection ul, .mainSection blockquote { + margin-bottom: 20px +} + +.mainSection blockquote { + font-family: 'Copse'; + font-size: 20px; + line-height: 28px; + color: #63a544; + background: url('/wp-content/themes/fivenew/img/blockquote.png') no-repeat top left; + padding-left: 65px; + min-height: 100px +} + +.mainSection blockquote p { + margin: 0 +} + +.mainSection h2, .mainSection h3, .mainSection h4, .mainSection h5, .mainSection h6 { + font-size: 26px; + line-height: 32px; + margin-bottom: 18px +} + +.mainSection img { + margin: 10px 0 +} + +.mainSection pre { + font: 13px "Courier 10 Pitch", Courier, monospace; + line-height: 1.5; + margin-bottom: 1.625em; + overflow: auto; + padding: 1.625em; + background: #DDDDDB; + white-space: pre-wrap; + white-space: -moz-pre-wrap; + white-space: -pre-wrap; + white-space: -o-pre-wrap; + word-wrap: break-word +} + +.mainSection code, .mainSection kbd, .mainSection samp, .mainSection var { + font: 13px Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; + color: #666; + background: #DDDDDB; + display: block; + padding: 5px +} + +.mainSection code { + display: inline +} + +.excerptHide { + height: 1000px; + overflow: hidden +} + +.excerptMore { + border-top: 1px dashed #171717; + padding-top: 20px; + margin-bottom: 50px +} + +.excerptMore span { + font: 13px Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; + display: block; + margin-bottom: 20px +} + +.sidebar { + width: 23%; + float: left +} + +.sidebar article { + margin-bottom: 50px +} + +.sidebar h4 { + font-size: 16px; + line-height: 23px +} + +.sidebar p { + font: 13px Monaco, Consolas, "Andale Mono", "DejaVu Sans Mono", monospace; + display: block; + margin-bottom: 20px +} + +.sidebar img { + margin: 10px 0 +} + +.sidebar .author { + background-color: #e7e7e7; + padding: 0px 10px 10px 12px; + -webkit-border-radius: 5px; + border-radius: 5px; + margin-bottom: 50px +} + +.sidebar .author .authorName { + max-width: 150px; + margin-left: 10px; + margin-top: 20px; + font-size: 16px; + color: #373737 +} + +.sidebar .author .authorName.noPic { + margin-left: 0 +} + +.sidebar .author .authorName.noPic span { + display: block; + padding-top: 10px; + margin-bottom: 20px +} + +.sidebar .author a { + font-size: 16px; + color: #373737; + word-break: break-all +} + +.catTitle { + border-bottom: 1px solid #9b9b9b +} + +body.archive #archive .mainSection article h4 { + font-size: 16px; + line-height: 22px; + color: #373737; + font-weight: bold +} + +.authorTitle { + font-size: 26px; + line-height: 30px +} + +#todays-five { + padding: 25px 0 +} + +#todays-five article { + padding: 25px 0; + text-align: center +} + +#todays-five article h2, #todays-five article p { + margin-left: 10%; + margin-right: 10% +} + +#todays-five article h2 { + margin-bottom: 22px +} + +#todays-five article h2 a { + font-size: 36px; + color: #373737 +} + +#todays-five article p { + margin-bottom: 12px +} + +#newsletter-section { + background-color: #e7e7e7; + padding: 35px 50px; + max-width: 520px; + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + border-radius: 10px; + -moz-background-clip: padding; + -webkit-background-clip: padding-box; + background-clip: padding-box; + margin: 0 auto 50px auto; + text-align: center +} + +#newsletter-section h2 { + line-height: 1em; + margin-bottom: 8px; + font-style: normal +} + +#newsletter-section p { + margin-bottom: 25px +} + +#newsletter-section form { + margin: 0 auto +} + +#newsletter-section form input { + display: inline +} + +#newsletter-section form input[type=email] { + margin-right: 20px; + background-color: white +} + +#newsletter article { + background-color: #e7e7e7; + padding: 35px 50px; + max-width: 520px; + -webkit-border-radius: 10px; + -moz-border-radius: 10px; + border-radius: 10px; + -moz-background-clip: padding; + -webkit-background-clip: padding-box; + background-clip: padding-box; + margin: 0 auto 50px auto; + text-align: center +} + +#newsletter article h2 { + line-height: 1em; + margin-bottom: 8px; + font-style: normal +} + +#newsletter article p { + margin-bottom: 25px +} + +#newsletter article form { + margin: 0 auto +} + +#newsletter article form input { + display: inline +} + +#newsletter article form input[type=email] { + margin-right: 20px; + background-color: white +} + +html.oldie { + font-family: Arial +} + +html.oldie .left { + float: left +} + +html.oldie .right { + float: right +} + +html.oldie .third { + width: 33.33333333%; + display: block; + float: left +} + +html.oldie .half { + width: 50%; + float: left; + display: block +} + +html.oldie .modalDialog { + display: none +} + +html.oldie #topNav nav { + max-width: 960px; + margin: 0 auto +} + +html.oldie #topNav ul { + overflow: hidden +} + +html.oldie #topNav ul.left { + float: left +} + +html.oldie #topNav ul.right { + float: right +} + +html.oldie #topNav ul li { + float: left; + display: block; + padding: 25px 0; + margin-right: 40px +} + +html.oldie #topNav ul li a { + color: #fff; + font-family: Arial; + font-size: 16px; + line-height: 22px +} + +html.oldie .five-logo { + padding: 100px 0; + display: block; + background: url('/wp-content/themes/fivenew/img/logo-five.png') center center no-repeat +} + +html.oldie #todays-five h2 { + font-family: 'Georgia', serif; + font-size: 36px; + line-height: 22px; + font-weight: bold +} + +html.oldie #todays-five .third { + width: 33.33333333%; + float: left; + display: block +} + +html.oldie #todays-five .half { + width: 50%; + float: left; + display: block +} + +html.oldie #newsletter-section { + background-color: #e7e7e7; + padding: 35px 50px; + max-width: 520px; + display: block; + margin: 0 auto 50px auto; + text-align: center +} + +html.oldie #newsletter-section h2 { + line-height: 1em; + margin-bottom: 8px; + font-style: normal +} + +html.oldie #newsletter-section p { + margin-bottom: 25px +} + +html.oldie #newsletter-section form { + margin: 0 auto +} + +html.oldie #newsletter-section form input { + display: inline; + color: black +} + +html.oldie #newsletter-section form input[type=email] { + margin-right: 20px; + background-color: white +} + +html.oldie #gform_1 .gform_description { + max-width: 280px; + display: block; + margin-bottom: 30px +} + +html.oldie #cats { + margin-top: 10px; + border-top: 1px solid #494949; + padding: 30px 0 +} + +html.oldie #cats h3 { + margin-right: 30px +} + +html.oldie #cats nav ul { + overflow: hidden +} + +html.oldie #cats nav ul li { + margin-bottom: 15px; + display: block; + float: left; + width: 25% +} + +html.oldie #cats nav ul li a { + border-bottom: 1px solid #63a544 +} + +html.oldie .social { + text-align: right +} + +html.oldie .twitter .inner { + border-left: 1px solid #494949; + padding: 0 70px 20px 70px +} + +html.oldie .author { + overflow: hidden +} + +html.oldie #archive .mainSection li { + margin-bottom: 20px; + float: left; + width: 50% +} + +html.oldie #archive .mainSection li article { + vertical-align: top; + display: block; + padding-right: 30px; + word-break: break-word; + height: 365px +} + +html.oldie #archive .mainSection li article p { + max-height: 286px; + overflow: hidden +} + +html[data-useragent*='MSIE 10.0'] .modalDialog { + display: none +} + +@media (max-width:480px) { + #topNav nav ul li { + padding: 5px + } + + #topNav nav ul li a { + font-size: 13px + } +} + +@media (min-width:481px) and (max-width:764px) { + #topNav nav ul li { + padding: 5px 10px + } +} + +@media (max-width:764px) { + .container { + text-align: center + } + + form input { + margin-left: auto; + margin-right: auto + } + + #topNav { + padding: 20px 0 + } + + #topNav nav ul { + text-align: center + } + + #topNav nav ul.social { + display: none + } + + #topNav nav ul li { + display: inline-block; + float: none; + margin: 0; + width: auto; + text-align: center; + font-size: 14px + } + + #topNav nav ul li a { + color: #e7e7e7 + } + + #archive .mainSection { + width: 100%; + margin-right: auto; + margin-left: auto; + float: none + } + + #archive .mainSection ul li { + margin-bottom: 30px; + float: none; + width: 100% + } + + #archive .sidebar { + display: none + } + + .container { + padding: 0 10px + } + + .container .five-logo { + background: url('/wp-content/themes/fivenew/img/logo-five.png') no-repeat right; + padding: 50px 0 + } + + .submit { + margin-bottom: 30px + } + + .submit form input { + margin: 0 auto 20px auto + } + + .submit .gform_heading { + margin-bottom: 10px + } + + .close { + right: 5px; + top: -4px + } + + #cats h3 { + margin-bottom: 20px + } + + #cats nav ul li { + width: 100%; + list-style: none + } +} + +@media (min-width:764px) { + .container .five-logo { + padding: 40px 0; + background: url('/wp-content/themes/fivenew/img/logo-five.png') no-repeat center + } + + body.home .container .five-logo { + padding: 100px 0; + background: url('/wp-content/themes/fivenew/img/logo-five.png') no-repeat center + } + + #archive .mainSection li { + margin-bottom: 20px; + float: left; + width: 50% + } + + #archive .mainSection li article { + vertical-align: top; + display: block; + padding-right: 30px; + word-break: break-word; + height: 365px + } + + #archive .mainSection li article p { + max-height: 286px; + overflow: hidden + } + + #topNav nav { + max-width: 940px; + margin: 0 auto + } + + #topNav nav ul { + padding-left: 10px + } + + #topNav nav ul.social { + padding: 0 + } + + #topNav nav ul.social li { + margin-right: 35px + } + + #topNav nav ul.social li a { + font-size: 12px + } + + #topNav nav ul li { + float: left; + margin-right: 40px; + padding: 25px 0 + } + + #topNav nav ul li a { + color: #e7e7e7 + } + + .left { + float: left + } + + .right { + float: right + } + + .half { + width: 50% + } + + .third { + width: 33.33333333% + } + + .twitter .inner { + border-left: 1px solid #494949; + padding: 0 70px 20px 70px + } + + #gform_1 .gform_description { + max-width: 280px; + display: block; + margin-bottom: 30px + } + + #cats h3 { + margin-right: 30px + } + + #cats form input[type=text] { + margin-right: 10px + } + + #cats nav ul li { + float: left; + width: 25%; + list-style: disc; + list-style-position: inside + } + + .social { + text-align: right + } +} \ No newline at end of file diff --git a/static/img/bg.gif b/static/img/bg.gif new file mode 100644 index 0000000..046575b Binary files /dev/null and b/static/img/bg.gif differ diff --git a/static/img/player-sprite.png b/static/img/player-sprite.png new file mode 100644 index 0000000..d1e7038 Binary files /dev/null and b/static/img/player-sprite.png differ diff --git a/static/js/app/appv2.coffee b/static/js/app/appv2.coffee index c6f03ed..e51a499 100644 --- a/static/js/app/appv2.coffee +++ b/static/js/app/appv2.coffee @@ -1,6 +1,6 @@ -define ['backbone', 'marionette', 'app.lib/router', 'app.lib/panningRegion', 'views/header', 'views/sidebar/sidebarView', +define ['backbone', 'marionette', 'app.lib/router', 'app.lib/panningRegion', 'app.lib/audioController', 'views/header', 'views/sidebar/sidebarView', 'models/mix/mixCollection'], -(Backbone, Marionette, DssRouter, PanningRegion, HeaderView, SidebarView, MixCollection) -> +(Backbone, Marionette, DssRouter, PanningRegion, AudioController, HeaderView, SidebarView, MixCollection) -> Marionette.Region.prototype.open = (view) -> @.$el.hide(); @.$el.html(view.el); @@ -8,6 +8,7 @@ define ['backbone', 'marionette', 'app.lib/router', 'app.lib/panningRegion', 'vi true App = new Marionette.Application(); + App.audioController = new AudioController() App.vent.on "mix:favourite", (model) -> console.log "App(vent): mix:favourite" @@ -50,7 +51,7 @@ define ['backbone', 'marionette', 'app.lib/router', 'app.lib/panningRegion', 'vi App.addInitializer -> console.log("App: routing starting"); App.Router = new DssRouter(); - return App.vent.trigger("routing:started"); + App.vent.trigger("routing:started"); App.addInitializer -> console.log("App: gobbling links"); diff --git a/static/js/app/appv2.js b/static/js/app/appv2.js index e62d1dc..9b8413b 100644 --- a/static/js/app/appv2.js +++ b/static/js/app/appv2.js @@ -1,6 +1,6 @@ // Generated by CoffeeScript 1.6.2 (function() { - define(['backbone', 'marionette', 'app.lib/router', 'app.lib/panningRegion', 'views/header', 'views/sidebar/sidebarView', 'models/mix/mixCollection'], function(Backbone, Marionette, DssRouter, PanningRegion, HeaderView, SidebarView, MixCollection) { + define(['backbone', 'marionette', 'app.lib/router', 'app.lib/panningRegion', 'app.lib/audioController', 'views/header', 'views/sidebar/sidebarView', 'models/mix/mixCollection'], function(Backbone, Marionette, DssRouter, PanningRegion, AudioController, HeaderView, SidebarView, MixCollection) { var App, sidebarView; Marionette.Region.prototype.open = function(view) { @@ -10,6 +10,7 @@ return true; }; App = new Marionette.Application(); + App.audioController = new AudioController(); App.vent.on("mix:favourite", function(model) { console.log("App(vent): mix:favourite"); model.save('favourited', !model.get('favourited'), { diff --git a/static/js/app/dss.bootstrapper.js b/static/js/app/dss.bootstrapper.js index f442f19..0e8190f 100644 --- a/static/js/app/dss.bootstrapper.js +++ b/static/js/app/dss.bootstrapper.js @@ -3,12 +3,15 @@ requirejs.config({ paths: { jquery: 'libs/jquery', backbone: 'libs/backbone/backbone', + 'backbone.babysitter': 'libs/backbone/backbone.babysitter', marionette: 'libs/backbone/backbone.marionette', + 'backbone.wreqr': 'libs/backbone/backbone.wreqr', ich: 'libs/ICanHaz', underscore: 'libs/backbone/underscore', text: 'libs/text', templates: '/templates', app: 'app/appv2', + vent: 'app/lib/eventAggregator', views: 'app/views', models: 'app/models', 'app.lib': 'app/lib', @@ -27,15 +30,15 @@ requirejs.config({ underscore: { exports: '_' }, - 'toastr': { - deps: ['jquery'], - exports: 'toastr' - } + 'toastr': { + deps: ['jquery'], + exports: 'toastr' + } } }); requirejs(['toastr', 'underscore', 'backbone', 'app'], function (toastr, _, Backbone, App) { - "require strict" + "use strict" console.log("Dss.Bootstrapper: primed"); App.start(); diff --git a/static/js/app/lib/audioController.coffee b/static/js/app/lib/audioController.coffee new file mode 100644 index 0000000..0134537 --- /dev/null +++ b/static/js/app/lib/audioController.coffee @@ -0,0 +1,35 @@ +define ['app', 'marionette', 'vent'], +(App, Marionette, vent) -> + class AudioController extends Marionette.Controller + + initialize: (options) -> + console.log "AudioController: initialize" + @listenTo(vent, 'mix:init', @mixInit) + @listenTo(vent, 'mix:pause', @mixPause) + @listenTo(vent, 'mix:play', @mixPlay) + + mixInit: (model) => + console.log "AudioController: mixInit" + id = model.get('id') + $.getJSON "/ajax/mix_stream_url/" + id + "/", (data) => + com.podnoms.settings.setupPlayerWrapper(id, data.stream_url) + com.podnoms.player.startPlaying + success: => + vent.trigger("mix:play", model) + com.podnoms.utils.checkPlayCount() + return + error: => + com.podnoms.utils.showWarning "Ooops", "Error playing mix. If you have a flash blocker, please disable it for this site. Otherwise, do please try again." + return + com.podnoms.storage.setItem "now_playing", id + return + + mixPlay: (model) -> + console.log("AudioController: mixPlay") + com.podnoms.player.resume(); + + mixPause: (model) -> + console.log("AudioController: mixPause") + com.podnoms.player.pause(); + AudioController + diff --git a/static/js/app/lib/audioController.js b/static/js/app/lib/audioController.js new file mode 100644 index 0000000..ff59f7c --- /dev/null +++ b/static/js/app/lib/audioController.js @@ -0,0 +1,62 @@ +// Generated by CoffeeScript 1.6.2 +(function() { + var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, + __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + + define(['app', 'marionette', 'vent'], function(App, Marionette, vent) { + var AudioController, _ref; + + AudioController = (function(_super) { + __extends(AudioController, _super); + + function AudioController() { + this.mixInit = __bind(this.mixInit, this); _ref = AudioController.__super__.constructor.apply(this, arguments); + return _ref; + } + + AudioController.prototype.initialize = function(options) { + console.log("AudioController: initialize"); + this.listenTo(vent, 'mix:init', this.mixInit); + this.listenTo(vent, 'mix:pause', this.mixPause); + return this.listenTo(vent, 'mix:play', this.mixPlay); + }; + + AudioController.prototype.mixInit = function(model) { + var id, + _this = this; + + console.log("AudioController: mixInit"); + id = model.get('id'); + return $.getJSON("/ajax/mix_stream_url/" + id + "/", function(data) { + com.podnoms.settings.setupPlayerWrapper(id, data.stream_url); + com.podnoms.player.startPlaying({ + success: function() { + vent.trigger("mix:play", model); + com.podnoms.utils.checkPlayCount(); + }, + error: function() { + com.podnoms.utils.showWarning("Ooops", "Error playing mix. If you have a flash blocker, please disable it for this site. Otherwise, do please try again."); + } + }); + com.podnoms.storage.setItem("now_playing", id); + }); + }; + + AudioController.prototype.mixPlay = function(model) { + console.log("AudioController: mixPlay"); + return com.podnoms.player.resume(); + }; + + AudioController.prototype.mixPause = function(model) { + console.log("AudioController: mixPause"); + return com.podnoms.player.pause(); + }; + + return AudioController; + + })(Marionette.Controller); + return AudioController; + }); + +}).call(this); diff --git a/static/js/app/lib/eventAggregator.coffee b/static/js/app/lib/eventAggregator.coffee index 919c700..1229714 100644 --- a/static/js/app/lib/eventAggregator.coffee +++ b/static/js/app/lib/eventAggregator.coffee @@ -1,6 +1,3 @@ -define ['marionette'], -(Marionette) -> - class EventAggregator extends Marionette.EventAggregator +define ['backbone.wreqr'], (Wreqr) -> + new Wreqr.EventAggregator - - EventAggregator \ No newline at end of file diff --git a/static/js/app/lib/eventAggregator.js b/static/js/app/lib/eventAggregator.js index d9dc866..55fe2e5 100644 --- a/static/js/app/lib/eventAggregator.js +++ b/static/js/app/lib/eventAggregator.js @@ -1,22 +1,7 @@ -// Generated by CoffeeScript 1.3.3 +// Generated by CoffeeScript 1.6.2 (function() { - var __hasProp = {}.hasOwnProperty, - __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; - - define(['marionette'], function(Marionette) { - var EventAggregator; - EventAggregator = (function(_super) { - - __extends(EventAggregator, _super); - - function EventAggregator() { - return EventAggregator.__super__.constructor.apply(this, arguments); - } - - return EventAggregator; - - })(Marionette.EventAggregator); - return EventAggregator; + define(['backbone.wreqr'], function(Wreqr) { + return new Wreqr.EventAggregator; }); }).call(this); diff --git a/static/js/app/models/user/userCollection.js b/static/js/app/models/user/userCollection.js index 9db6a7e..29367d8 100644 --- a/static/js/app/models/user/userCollection.js +++ b/static/js/app/models/user/userCollection.js @@ -1,16 +1,17 @@ -// Generated by CoffeeScript 1.3.3 +// Generated by CoffeeScript 1.6.2 (function() { var __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; define(['backbone', 'models/user/userItem', 'app.lib/backbone.dss.model.collection'], function(Backbone, UserItem, DssCollection) { - var UserCollection; - UserCollection = (function(_super) { + var UserCollection, _ref; + UserCollection = (function(_super) { __extends(UserCollection, _super); function UserCollection() { - return UserCollection.__super__.constructor.apply(this, arguments); + _ref = UserCollection.__super__.constructor.apply(this, arguments); + return _ref; } UserCollection.prototype.model = UserItem; diff --git a/static/js/app/views/mix/mixItemView.coffee b/static/js/app/views/mix/mixItemView.coffee index 02f7347..e00d5cd 100644 --- a/static/js/app/views/mix/mixItemView.coffee +++ b/static/js/app/views/mix/mixItemView.coffee @@ -1,27 +1,32 @@ -define ['moment', 'app', 'marionette', 'models/comment/commentCollection', 'views/comment/commentListView', 'text!/tpl/MixListItemView'], -(moment, App, Marionette, CommentsCollection, CommentsListView, Template) -> +define ['moment', 'app', 'vent', 'marionette', 'models/comment/commentCollection', 'views/comment/commentListView', 'text!/tpl/MixListItemView'], +(moment, App, vent, Marionette, CommentsCollection, CommentsListView, Template) -> class MixItemView extends Marionette.ItemView template: _.template(Template) tagName: @tagName or "li" className: @className or "" events: { - "click .play-button-small-start": "startMix", - "click .play-button-small-resume": "resumeMix", - "click .play-button-small-pause": "pauseMix", + "click .play-button-small-start": "doStart", + "click .play-button-small-resume": "doResume", + "click .play-button-small-pause": "doPause", "click .mix-link": "mixLink", - "click .like-button a": "likeMix", - "click .favourite-button a": "favouriteMix", - "click .share-button": "shareMix", - "click .download-button a": "downloadMix" + "click .like-button a": "mixLike", + "click .favourite-button a": "mixFavourite", + "click .share-button": "mixShare", + "click .download-button a": "mixDownload" + } + + ui: { + playButton: ".play-button-small" } initialize: => @listenTo(@model, 'change:favourited', @render) @listenTo(@model, 'change:liked', @render) + @listenTo(vent, 'mix:play', @mixPlay) + @listenTo(vent, 'mix:pause', @mixPause) true - onRender: => id = @model.get('id') if @model.get('duration') @@ -31,40 +36,11 @@ define ['moment', 'app', 'marionette', 'models/comment/commentCollection', 'view #check if we're currently playing if com.podnoms.player.isPlayingId @model.id - com.podnoms.settings.setupPlayer @model.toJSON() + com.podnoms.settings.setupPlayerWrapper @model.get('id') @renderGenres() return - startMix: => - console.log("MixItemView: starting mix") - id = @model.get('id') - $.getJSON "/ajax/mix_stream_url/" + id + "/", (data) -> - com.podnoms.settings.setupPlayer(data, id) - com.podnoms.player.startPlaying - success: -> - window._eventAggregator.trigger "track_playing" - window._eventAggregator.trigger "track_changed", data - com.podnoms.utils.checkPlayCount() - return - error: -> - com.podnoms.utils.showWarning "Ooops", "Error playing mix. If you have a flash blocker, please disable it for this site. Otherwise, do please try again." - - com.podnoms.storage.setItem "now_playing", id - return - - pauseMix: -> - console.log("MixItemView: pauseMix") - com.podnoms.player.pause(); - @.trigger("mix:paused", @model); - true - - resumeMix: -> - console.log("MixItemView: resumeMix") - com.podnoms.player.resume(); - @trigger("mix:resumed", @model); - true - renderGenres: => el = @el $.each @model.get("genre-list"), (data) -> @@ -84,19 +60,55 @@ define ['moment', 'app', 'marionette', 'models/comment/commentCollection', 'view true true - favouriteMix: -> + doStart: => + console.log("MixItemView: mixStart") + this.ui.playButton + .toggleClass('play-button-small-start', false) + .toggleClass('play-button-small-resume', false) + .toggleClass('play-button-small-pause', true) + + vent.trigger('mix:init', @model) + return + + doPause: -> + console.log("MixItemView: mixPause") + vent.trigger("mix:pause", @model); + true + + doResume: -> + console.log("MixItemView: mixResume") + vent.trigger("mix:play", @model); + true + + mixPlay: (model) -> + if (@model.get('id') == model.get('id')) + this.ui.playButton + .toggleClass('play-button-small-start', false) + .toggleClass('play-button-small-resume', false) + .toggleClass('play-button-small-pause', true) + return + + mixPause: (model) -> + if (@model.get('id') == model.get('id')) + this.ui.playButton + .toggleClass('play-button-small-start', false) + .toggleClass('play-button-small-resume', true) + .toggleClass('play-button-small-pause', false) + return + + mixFavourite: -> console.log("MixItemView: favouriteMix") app = require('app') app.vent.trigger("mix:favourite", @model) true - likeMix: -> + mixLike: -> console.log("MixItemView: likeMix") app = require('app') app.vent.trigger("mix:like", @model) true - shareMix: (e) -> + mixShare: (e) -> console.log("MixItemView: shareMix") mode = $(e.currentTarget).data("mode"); console.log("MixItemView: "+ mode) diff --git a/static/js/app/views/mix/mixItemView.js b/static/js/app/views/mix/mixItemView.js index b8759be..2e14c4b 100644 --- a/static/js/app/views/mix/mixItemView.js +++ b/static/js/app/views/mix/mixItemView.js @@ -1,26 +1,22 @@ -// Generated by CoffeeScript 1.3.3 +// Generated by CoffeeScript 1.6.2 (function() { var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }, __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; - define(['moment', 'app', 'marionette', 'models/comment/commentCollection', 'views/comment/commentListView', 'text!/tpl/MixListItemView'], function(moment, App, Marionette, CommentsCollection, CommentsListView, Template) { - var MixItemView; - MixItemView = (function(_super) { + define(['moment', 'app', 'vent', 'marionette', 'models/comment/commentCollection', 'views/comment/commentListView', 'text!/tpl/MixListItemView'], function(moment, App, vent, Marionette, CommentsCollection, CommentsListView, Template) { + var MixItemView, _ref; + MixItemView = (function(_super) { __extends(MixItemView, _super); function MixItemView() { + this.doStart = __bind(this.doStart, this); this.renderComments = __bind(this.renderComments, this); - this.renderGenres = __bind(this.renderGenres, this); - - this.startMix = __bind(this.startMix, this); - this.onRender = __bind(this.onRender, this); - - this.initialize = __bind(this.initialize, this); - return MixItemView.__super__.constructor.apply(this, arguments); + this.initialize = __bind(this.initialize, this); _ref = MixItemView.__super__.constructor.apply(this, arguments); + return _ref; } MixItemView.prototype.template = _.template(Template); @@ -30,24 +26,31 @@ MixItemView.prototype.className = MixItemView.className || ""; MixItemView.prototype.events = { - "click .play-button-small-start": "startMix", - "click .play-button-small-resume": "resumeMix", - "click .play-button-small-pause": "pauseMix", + "click .play-button-small-start": "doStart", + "click .play-button-small-resume": "doResume", + "click .play-button-small-pause": "doPause", "click .mix-link": "mixLink", - "click .like-button a": "likeMix", - "click .favourite-button a": "favouriteMix", - "click .share-button": "shareMix", - "click .download-button a": "downloadMix" + "click .like-button a": "mixLike", + "click .favourite-button a": "mixFavourite", + "click .share-button": "mixShare", + "click .download-button a": "mixDownload" + }; + + MixItemView.prototype.ui = { + playButton: ".play-button-small" }; MixItemView.prototype.initialize = function() { this.listenTo(this.model, 'change:favourited', this.render); this.listenTo(this.model, 'change:liked', this.render); + this.listenTo(vent, 'mix:play', this.mixPlay); + this.listenTo(vent, 'mix:pause', this.mixPause); return true; }; MixItemView.prototype.onRender = function() { var id, totalDuration, totalDurationText; + id = this.model.get('id'); if (this.model.get('duration')) { totalDuration = moment.duration(this.model.get('duration'), "seconds"); @@ -55,47 +58,14 @@ $('#player-duration-' + id, this.el).text(totalDurationText); } if (com.podnoms.player.isPlayingId(this.model.id)) { - com.podnoms.settings.setupPlayer(this.model.toJSON()); + com.podnoms.settings.setupPlayerWrapper(this.model.get('id')); } this.renderGenres(); }; - MixItemView.prototype.startMix = function() { - var id; - console.log("MixItemView: starting mix"); - id = this.model.get('id'); - $.getJSON("/ajax/mix_stream_url/" + id + "/", function(data) { - com.podnoms.settings.setupPlayer(data, id); - com.podnoms.player.startPlaying({ - success: function() { - window._eventAggregator.trigger("track_playing"); - window._eventAggregator.trigger("track_changed", data); - com.podnoms.utils.checkPlayCount(); - }, - error: function() { - return com.podnoms.utils.showWarning("Ooops", "Error playing mix. If you have a flash blocker, please disable it for this site. Otherwise, do please try again."); - } - }); - return com.podnoms.storage.setItem("now_playing", id); - }); - }; - - MixItemView.prototype.pauseMix = function() { - console.log("MixItemView: pauseMix"); - com.podnoms.player.pause(); - this.trigger("mix:paused", this.model); - return true; - }; - - MixItemView.prototype.resumeMix = function() { - console.log("MixItemView: resumeMix"); - com.podnoms.player.resume(); - this.trigger("mix:resumed", this.model); - return true; - }; - MixItemView.prototype.renderGenres = function() { var el; + el = this.el; $.each(this.model.get("genre-list"), function(data) { $("#genre-list", el).append('' + this.text + ''); @@ -106,6 +76,7 @@ MixItemView.prototype.renderComments = function() { var comments; + comments = new CommentsCollection(); comments.url = this.model.get("resource_uri") + "comments/"; comments.mix_id = this.model.id; @@ -113,6 +84,7 @@ comments.fetch({ success: function(data) { var content; + console.log(data); content = new CommentsListView({ collection: comments @@ -124,24 +96,57 @@ return true; }; - MixItemView.prototype.favouriteMix = function() { + MixItemView.prototype.doStart = function() { + console.log("MixItemView: mixStart"); + this.ui.playButton.toggleClass('play-button-small-start', false).toggleClass('play-button-small-resume', false).toggleClass('play-button-small-pause', true); + vent.trigger('mix:init', this.model); + }; + + MixItemView.prototype.doPause = function() { + console.log("MixItemView: mixPause"); + vent.trigger("mix:pause", this.model); + return true; + }; + + MixItemView.prototype.doResume = function() { + console.log("MixItemView: mixResume"); + vent.trigger("mix:play", this.model); + return true; + }; + + MixItemView.prototype.mixPlay = function(model) { + if (this.model.get('id') === model.get('id')) { + this.ui.playButton.toggleClass('play-button-small-start', false).toggleClass('play-button-small-resume', false).toggleClass('play-button-small-pause', true); + } + }; + + MixItemView.prototype.mixPause = function(model) { + if (this.model.get('id') === model.get('id')) { + this.ui.playButton.toggleClass('play-button-small-start', false).toggleClass('play-button-small-resume', true).toggleClass('play-button-small-pause', false); + } + }; + + MixItemView.prototype.mixFavourite = function() { var app; + console.log("MixItemView: favouriteMix"); app = require('app'); app.vent.trigger("mix:favourite", this.model); return true; }; - MixItemView.prototype.likeMix = function() { + MixItemView.prototype.mixLike = function() { var app; + console.log("MixItemView: likeMix"); app = require('app'); app.vent.trigger("mix:like", this.model); return true; }; - MixItemView.prototype.shareMix = function(e) { + MixItemView.prototype.mixShare = function(e) { var app, mode; + console.log("MixItemView: shareMix"); mode = $(e.currentTarget).data("mode"); console.log("MixItemView: " + mode); diff --git a/static/js/app/views/mix/mixListView.coffee b/static/js/app/views/mix/mixListView.coffee index b7fe6ba..45e8015 100644 --- a/static/js/app/views/mix/mixListView.coffee +++ b/static/js/app/views/mix/mixListView.coffee @@ -1,5 +1,5 @@ -define ['marionette', 'models/mix/mixCollection', 'views/mix/mixItemView', 'text!/tpl/MixListView'], -(Marionette, MixCollection, MixItemView, Template) -> +define ['marionette', 'vent', 'models/mix/mixCollection', 'views/mix/mixItemView', 'text!/tpl/MixListView'], +(Marionette, vent, MixCollection, MixItemView, Template) -> class MixListView extends Marionette.CompositeView template: _.template(Template) @@ -7,6 +7,8 @@ define ['marionette', 'models/mix/mixCollection', 'views/mix/mixItemView', 'text itemView: MixItemView itemViewContainer: "#mix-list-container-ul" + currentMix = -1 + initialize: -> console.log "MixListView: initialize" @collection = new MixCollection() @@ -15,10 +17,21 @@ define ['marionette', 'models/mix/mixCollection', 'views/mix/mixItemView', 'text success: => console.log("MixListView: Collection fetched") @tabChanged('latest') + @listenTo(vent, 'mix:play', @mixPlay) true ) return + mixPlay: (model) -> + console.log "MixListView: mixPlay" + """ + if currentMix != -1 + v = @children.findByModelCid(currentMix) + v.mixPause() + """ + currentMix = model.cid + return + onRender: -> $('#li-' + @options.type, @el).addClass('active') true diff --git a/static/js/app/views/mix/mixListView.js b/static/js/app/views/mix/mixListView.js index cbb0652..2bc1d4c 100644 --- a/static/js/app/views/mix/mixListView.js +++ b/static/js/app/views/mix/mixListView.js @@ -3,10 +3,12 @@ var __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; - define(['marionette', 'models/mix/mixCollection', 'views/mix/mixItemView', 'text!/tpl/MixListView'], function(Marionette, MixCollection, MixItemView, Template) { + define(['marionette', 'vent', 'models/mix/mixCollection', 'views/mix/mixItemView', 'text!/tpl/MixListView'], function(Marionette, vent, MixCollection, MixItemView, Template) { var MixListView, _ref; MixListView = (function(_super) { + var currentMix; + __extends(MixListView, _super); function MixListView() { @@ -22,6 +24,8 @@ MixListView.prototype.itemViewContainer = "#mix-list-container-ul"; + currentMix = -1; + MixListView.prototype.initialize = function() { var _this = this; @@ -32,11 +36,18 @@ success: function() { console.log("MixListView: Collection fetched"); _this.tabChanged('latest'); + _this.listenTo(vent, 'mix:play', _this.mixPlay); return true; } }); }; + MixListView.prototype.mixPlay = function(model) { + console.log("MixListView: mixPlay"); + "if currentMix != -1\n v = @children.findByModelCid(currentMix)\n v.mixPause()"; + currentMix = model.cid; + }; + MixListView.prototype.onRender = function() { $('#li-' + this.options.type, this.el).addClass('active'); return true; diff --git a/static/js/app/views/sidebar/sidebarView.coffee b/static/js/app/views/sidebar/sidebarView.coffee index ff89965..ef09405 100644 --- a/static/js/app/views/sidebar/sidebarView.coffee +++ b/static/js/app/views/sidebar/sidebarView.coffee @@ -1,19 +1,42 @@ -define ['underscore', 'backbone', 'marionette', 'views/activity/activityListView', 'text!/tpl/SidebarView'], -(_, Backbone, Marionette, ActivityListView, Template) -> +define ['underscore', 'backbone', 'marionette', 'vent', 'views/activity/activityListView', 'views/widgets/nowPlayingView', 'text!/tpl/SidebarView'], +(_, Backbone, Marionette, vent, ActivityListView, NowPlayingView, Template) -> + class SidebarView extends Marionette.Layout template: _.template(Template) - className: "tabbable" regions: topRegion: '#sidebar-top-content' streamRegion: '#sidebar-stream-content' + initialize: -> console.log "SidebarView: initialize" + this.listenTo(vent, 'mix:init', @mixInit) + this.listenTo(vent, 'mix:play', @mixPlay) + this.listenTo(vent, 'mix:pause', @mixPause) + return + + onRender: -> + console.log "SidebarView: onRender" return onShow: -> console.log "SidebarView: onShow" - #this.topRegion.show(new NowPlayingView()) - this.streamRegion.show(new ActivityListView()) + @streamRegion.show(new ActivityListView()) + $(@topRegion.el).hide() + """ + @topRegion.show( + new NowPlayingView( + model: new Backbone.Model({ + item_url: "fdskjfhdsk", title: "Argle bargle", user_profile_url: "/", user_name: "Foo Ferra" + }) + )) + """ return + mixInit: (model) -> + console.log "SidebarView: mixInit" + $(@topRegion.el).show() + @topRegion.show(new NowPlayingView({model: model})) + + SidebarView + diff --git a/static/js/app/views/sidebar/sidebarView.js b/static/js/app/views/sidebar/sidebarView.js index f43bad5..0aa6aa6 100644 --- a/static/js/app/views/sidebar/sidebarView.js +++ b/static/js/app/views/sidebar/sidebarView.js @@ -1,22 +1,21 @@ -// Generated by CoffeeScript 1.3.3 +// Generated by CoffeeScript 1.6.2 (function() { var __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; - define(['underscore', 'backbone', 'marionette', 'views/activity/activityListView', 'text!/tpl/SidebarView'], function(_, Backbone, Marionette, ActivityListView, Template) { - var SidebarView; - return SidebarView = (function(_super) { + define(['underscore', 'backbone', 'marionette', 'vent', 'views/activity/activityListView', 'views/widgets/nowPlayingView', 'text!/tpl/SidebarView'], function(_, Backbone, Marionette, vent, ActivityListView, NowPlayingView, Template) { + var SidebarView, _ref; + SidebarView = (function(_super) { __extends(SidebarView, _super); function SidebarView() { - return SidebarView.__super__.constructor.apply(this, arguments); + _ref = SidebarView.__super__.constructor.apply(this, arguments); + return _ref; } SidebarView.prototype.template = _.template(Template); - SidebarView.prototype.className = "tabbable"; - SidebarView.prototype.regions = { topRegion: '#sidebar-top-content', streamRegion: '#sidebar-stream-content' @@ -24,16 +23,34 @@ SidebarView.prototype.initialize = function() { console.log("SidebarView: initialize"); + this.listenTo(vent, 'mix:init', this.mixInit); + this.listenTo(vent, 'mix:play', this.mixPlay); + this.listenTo(vent, 'mix:pause', this.mixPause); + }; + + SidebarView.prototype.onRender = function() { + console.log("SidebarView: onRender"); }; SidebarView.prototype.onShow = function() { console.log("SidebarView: onShow"); this.streamRegion.show(new ActivityListView()); + $(this.topRegion.el).hide(); + "@topRegion.show(\n new NowPlayingView(\n model: new Backbone.Model({\n item_url: \"fdskjfhdsk\", title: \"Argle bargle\", user_profile_url: \"/\", user_name: \"Foo Ferra\"\n })\n ))"; + }; + + SidebarView.prototype.mixInit = function(model) { + console.log("SidebarView: mixInit"); + $(this.topRegion.el).show(); + return this.topRegion.show(new NowPlayingView({ + model: model + })); }; return SidebarView; })(Marionette.Layout); + return SidebarView; }); }).call(this); diff --git a/static/js/app/views/user/userListView.coffee b/static/js/app/views/user/userListView.coffee index f18d9a9..e4b3d2a 100644 --- a/static/js/app/views/user/userListView.coffee +++ b/static/js/app/views/user/userListView.coffee @@ -1,4 +1,4 @@ -define ['marionette', 'models/user/userCollection', 'views/user/userItemView', 'text!/tpl/UserListView'], +define ['marionette', 'models/user/userCollection', 'views/user/userItemView', 'text!/tpl/UserListView', 'libs/jquery.dataTables'], (Marionette, UserCollection, UserItemView, Template) -> class UserListView extends Marionette.CompositeView @@ -14,7 +14,7 @@ define ['marionette', 'models/user/userCollection', 'views/user/userItemView', ' data: @options success: => console.log("UserListView: Collection fetched") - $(@el).tablesorter() + $(@el).dataTable sDom: "<'row'<'span6'l><'span6'f>r>t<'row'<'span6'i><'span6'p>>" return ) return diff --git a/static/js/app/views/user/userListView.js b/static/js/app/views/user/userListView.js index 8ac0fdb..6a26191 100644 --- a/static/js/app/views/user/userListView.js +++ b/static/js/app/views/user/userListView.js @@ -1,16 +1,17 @@ -// Generated by CoffeeScript 1.3.3 +// Generated by CoffeeScript 1.6.2 (function() { var __hasProp = {}.hasOwnProperty, __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; - define(['marionette', 'models/user/userCollection', 'views/user/userItemView', 'text!/tpl/UserListView'], function(Marionette, UserCollection, UserItemView, Template) { - var UserListView; - UserListView = (function(_super) { + define(['marionette', 'models/user/userCollection', 'views/user/userItemView', 'text!/tpl/UserListView', 'libs/jquery.dataTables'], function(Marionette, UserCollection, UserItemView, Template) { + var UserListView, _ref; + UserListView = (function(_super) { __extends(UserListView, _super); function UserListView() { - return UserListView.__super__.constructor.apply(this, arguments); + _ref = UserListView.__super__.constructor.apply(this, arguments); + return _ref; } UserListView.prototype.template = _.template(Template); @@ -23,13 +24,16 @@ UserListView.prototype.initialize = function() { var _this = this; + console.log("UserListView: initialize"); this.collection = new UserCollection(); this.collection.fetch({ data: this.options, success: function() { console.log("UserListView: Collection fetched"); - $(_this.el).tablesorter(); + $(_this.el).dataTable({ + sDom: "<'row'<'span6'l><'span6'f>r>t<'row'<'span6'i><'span6'p>>" + }); } }); }; diff --git a/static/js/app/views/widgets/nowPlayingView.coffee b/static/js/app/views/widgets/nowPlayingView.coffee new file mode 100644 index 0000000..8c19e8f --- /dev/null +++ b/static/js/app/views/widgets/nowPlayingView.coffee @@ -0,0 +1,48 @@ +define ['marionette', 'vent', 'text!/tpl/NowPlayingView'], +(Marionette, vent, Template) -> + + class NowPlayingView extends Marionette.ItemView + template: _.template(Template) + className: "now-playing" + + events: { + "click .now-playing-play": "doPlay", + "click .now-playing-pause": "doPause" + } + + initialize: -> + console.log "NowPlayingView: initialize" + @listenTo(vent, 'mix:play', @mixPlay) + @listenTo(vent, 'mix:pause', @mixPause) + true + + onRender: -> + @mixPlay() + true + + mixPause: (model) -> + console.log "NowPlayingView: mixPause" + $('#now-playing-playing-toggle', @el) + .toggleClass('now-playing-play', true) + .toggleClass('now-playing-pause', false) + true + + mixPlay: (model) -> + console.log "NowPlayingView: mixPlay" + $('#now-playing-playing-toggle', @el) + .toggleClass('now-playing-play', false) + .toggleClass('now-playing-pause', true) + true + + doPlay: -> + console.log "NowPlayingView: doPlay" + vent.trigger('mix:play', @model) + true + + doPause: -> + console.log "NowPlayingView: doPause" + vent.trigger('mix:pause', @model) + true + + NowPlayingView + diff --git a/static/js/app/views/widgets/nowPlayingView.js b/static/js/app/views/widgets/nowPlayingView.js new file mode 100644 index 0000000..53c0212 --- /dev/null +++ b/static/js/app/views/widgets/nowPlayingView.js @@ -0,0 +1,68 @@ +// Generated by CoffeeScript 1.6.2 +(function() { + var __hasProp = {}.hasOwnProperty, + __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; }; + + define(['marionette', 'vent', 'text!/tpl/NowPlayingView'], function(Marionette, vent, Template) { + var NowPlayingView, _ref; + + NowPlayingView = (function(_super) { + __extends(NowPlayingView, _super); + + function NowPlayingView() { + _ref = NowPlayingView.__super__.constructor.apply(this, arguments); + return _ref; + } + + NowPlayingView.prototype.template = _.template(Template); + + NowPlayingView.prototype.className = "now-playing"; + + NowPlayingView.prototype.events = { + "click .now-playing-play": "doPlay", + "click .now-playing-pause": "doPause" + }; + + NowPlayingView.prototype.initialize = function() { + console.log("NowPlayingView: initialize"); + this.listenTo(vent, 'mix:play', this.mixPlay); + this.listenTo(vent, 'mix:pause', this.mixPause); + return true; + }; + + NowPlayingView.prototype.onRender = function() { + this.mixPlay(); + return true; + }; + + NowPlayingView.prototype.mixPause = function(model) { + console.log("NowPlayingView: mixPause"); + $('#now-playing-playing-toggle', this.el).toggleClass('now-playing-play', true).toggleClass('now-playing-pause', false); + return true; + }; + + NowPlayingView.prototype.mixPlay = function(model) { + console.log("NowPlayingView: mixPlay"); + $('#now-playing-playing-toggle', this.el).toggleClass('now-playing-play', false).toggleClass('now-playing-pause', true); + return true; + }; + + NowPlayingView.prototype.doPlay = function() { + console.log("NowPlayingView: doPlay"); + vent.trigger('mix:play', this.model); + return true; + }; + + NowPlayingView.prototype.doPause = function() { + console.log("NowPlayingView: doPause"); + vent.trigger('mix:pause', this.model); + return true; + }; + + return NowPlayingView; + + })(Marionette.ItemView); + return NowPlayingView; + }); + +}).call(this); diff --git a/static/js/com.podnoms.player.js b/static/js/com.podnoms.player.js index 845b8fc..a9c6b64 100644 --- a/static/js/com.podnoms.player.js +++ b/static/js/com.podnoms.player.js @@ -58,9 +58,6 @@ com.podnoms.player = { }, _whilePlaying: function () { if (!this.trackLoaded) { - this.playButtonEl - .removeClass('play-button-small-loading') - .addClass('play-button-small-pause'); this.trackLoaded = true; } this.currentPosition = this.currentSound.position; @@ -93,12 +90,6 @@ com.podnoms.player = { soundManager.destroySound(this.currentSound.sID); } this.trackLoaded = false; - if (this.playButtonEl != undefined) - this.playButtonEl - .removeClass('play-button-small-pause') - .removeClass('play-button-small-loading') - .addClass('play-button-small-start'); - this.currentId = null; if (success != undefined) success(); @@ -110,7 +101,6 @@ com.podnoms.player = { this.seekHeadEl = options.seekHeadEl; this.playHeadEl = options.playHeadEl; this.loadingEl = options.loadingEl; - this.playButtonEl = options.playButtonEl; this.currentPath = options.url; }, _setupParams: function () { @@ -151,13 +141,6 @@ com.podnoms.player = { setupPlayer: function (options) { this._parseOptions(options); this._setupParams(); - if (this.isPlayingId(options.id)) { - this.playButtonEl - .removeClass('play-button-small-start') - .removeClass('play-button-small-loading') - .addClass('play-button-small-pause'); - } - }, startPlaying: function (options) { var ref = this; @@ -219,21 +202,12 @@ com.podnoms.player = { play: function () { this.currentSound.play(); - this.playButtonEl - .removeClass('play-button-small-start') - .addClass('play-button-small-loading'); }, pause: function () { this.currentSound.pause(); - this.playButtonEl - .removeClass('play-button-small-pause') - .addClass('play-button-small-resume'); }, resume: function () { this.currentSound.resume(); - this.playButtonEl - .removeClass('play-button-small-resume') - .addClass('play-button-small-pause'); }, forward: function (increment) { diff --git a/static/js/com.podnoms.utils.js b/static/js/com.podnoms.utils.js index 1a44abe..9347fe4 100644 --- a/static/js/com.podnoms.utils.js +++ b/static/js/com.podnoms.utils.js @@ -109,7 +109,7 @@ com.podnoms.utils = { if (document.cookie.indexOf('sessionId')) { $.getJSON('/ajax/session_play_count', function (data) { if ((data.play_count != 0) && (data.play_count % 5) == 0) { - com.podnoms.utils.modal('tpl/PlayCountLoginAlert'); + com.podnoms.utils.showAlert('tpl/PlayCountLoginAlert'); } }); } diff --git a/static/js/libs/backbone/backbone.babysitter.js b/static/js/libs/backbone/backbone.babysitter.js new file mode 100644 index 0000000..235410b --- /dev/null +++ b/static/js/libs/backbone/backbone.babysitter.js @@ -0,0 +1,177 @@ +// Backbone.BabySitter +// ------------------- +// v0.0.6 +// +// Copyright (c)2013 Derick Bailey, Muted Solutions, LLC. +// Distributed under MIT license +// +// http://github.com/babysitterjs/backbone.babysitter + +(function (root, factory) { + if (typeof exports === 'object') { + + var underscore = require('underscore'); + var backbone = require('backbone'); + + module.exports = factory(underscore, backbone); + + } else if (typeof define === 'function' && define.amd) { + + define(['underscore', 'backbone'], factory); + + } +}(this, function (_, Backbone) { + "option strict"; + + // Backbone.ChildViewContainer +// --------------------------- +// +// Provide a container to store, retrieve and +// shut down child views. + +Backbone.ChildViewContainer = (function(Backbone, _){ + + // Container Constructor + // --------------------- + + var Container = function(views){ + this._views = {}; + this._indexByModel = {}; + this._indexByCustom = {}; + this._updateLength(); + + _.each(views, this.add, this); + }; + + // Container Methods + // ----------------- + + _.extend(Container.prototype, { + + // Add a view to this container. Stores the view + // by `cid` and makes it searchable by the model + // cid (and model itself). Optionally specify + // a custom key to store an retrieve the view. + add: function(view, customIndex){ + var viewCid = view.cid; + + // store the view + this._views[viewCid] = view; + + // index it by model + if (view.model){ + this._indexByModel[view.model.cid] = viewCid; + } + + // index by custom + if (customIndex){ + this._indexByCustom[customIndex] = viewCid; + } + + this._updateLength(); + }, + + // Find a view by the model that was attached to + // it. Uses the model's `cid` to find it. + findByModel: function(model){ + return this.findByModelCid(model.cid); + }, + + // Find a view by the `cid` of the model that was attached to + // it. Uses the model's `cid` to find the view `cid` and + // retrieve the view using it. + findByModelCid: function(modelCid){ + var viewCid = this._indexByModel[modelCid]; + return this.findByCid(viewCid); + }, + + // Find a view by a custom indexer. + findByCustom: function(index){ + var viewCid = this._indexByCustom[index]; + return this.findByCid(viewCid); + }, + + // Find by index. This is not guaranteed to be a + // stable index. + findByIndex: function(index){ + return _.values(this._views)[index]; + }, + + // retrieve a view by it's `cid` directly + findByCid: function(cid){ + return this._views[cid]; + }, + + // Remove a view + remove: function(view){ + var viewCid = view.cid; + + // delete model index + if (view.model){ + delete this._indexByModel[view.model.cid]; + } + + // delete custom index + _.any(this._indexByCustom, function(cid, key) { + if (cid === viewCid) { + delete this._indexByCustom[key]; + return true; + } + }, this); + + // remove the view from the container + delete this._views[viewCid]; + + // update the length + this._updateLength(); + }, + + // Call a method on every view in the container, + // passing parameters to the call method one at a + // time, like `function.call`. + call: function(method){ + this.apply(method, _.tail(arguments)); + }, + + // Apply a method on every view in the container, + // passing parameters to the call method one at a + // time, like `function.apply`. + apply: function(method, args){ + _.each(this._views, function(view){ + if (_.isFunction(view[method])){ + view[method].apply(view, args || []); + } + }); + }, + + // Update the `.length` attribute on this container + _updateLength: function(){ + this.length = _.size(this._views); + } + }); + + // Borrowing this code from Backbone.Collection: + // http://backbonejs.org/docs/backbone.html#section-106 + // + // Mix in methods from Underscore, for iteration, and other + // collection related features. + var methods = ['forEach', 'each', 'map', 'find', 'detect', 'filter', + 'select', 'reject', 'every', 'all', 'some', 'any', 'include', + 'contains', 'invoke', 'toArray', 'first', 'initial', 'rest', + 'last', 'without', 'isEmpty', 'pluck']; + + _.each(methods, function(method) { + Container.prototype[method] = function() { + var views = _.values(this._views); + var args = [views].concat(_.toArray(arguments)); + return _[method].apply(_, args); + }; + }); + + // return the public API + return Container; +})(Backbone, _); + + return Backbone.ChildViewContainer; + +})); diff --git a/static/js/libs/backbone/backbone.marionette.js b/static/js/libs/backbone/backbone.marionette.js index 4380894..6ff513e 100644 --- a/static/js/libs/backbone/backbone.marionette.js +++ b/static/js/libs/backbone/backbone.marionette.js @@ -17,473 +17,24 @@ * https://github.com/marionettejs/backbone.wreqr/ */ -// Backbone.BabySitter -// ------------------- -// v0.0.5 -// -// Copyright (c)2013 Derick Bailey, Muted Solutions, LLC. -// Distributed under MIT license -// -// http://github.com/babysitterjs/backbone.babysitter +(function (root, factory) { + if (typeof exports === 'object') { -// Backbone.ChildViewContainer -// --------------------------- -// -// Provide a container to store, retrieve and -// shut down child views. + var underscore = require('underscore'); + var backbone = require('backbone'); + var wreqr = require('backbone.wreqr'); + var babysitter = require('backbone.babysitter'); -Backbone.ChildViewContainer = (function(Backbone, _){ - - // Container Constructor - // --------------------- + module.exports = factory(underscore, backbone, wreqr, babysitter); - var Container = function(initialViews){ - this._views = {}; - this._indexByModel = {}; - this._indexByCollection = {}; - this._indexByCustom = {}; - this._updateLength(); + } else if (typeof define === 'function' && define.amd) { - this._addInitialViews(initialViews); - }; + define(['underscore', 'backbone', 'backbone.wreqr', 'backbone.babysitter'], factory); - // Container Methods - // ----------------- + } +}(this, function (_, Backbone) { - _.extend(Container.prototype, { - - // Add a view to this container. Stores the view - // by `cid` and makes it searchable by the model - // and/or collection of the view. Optionally specify - // a custom key to store an retrieve the view. - add: function(view, customIndex){ - var viewCid = view.cid; - - // store the view - this._views[viewCid] = view; - - // index it by model - if (view.model){ - this._indexByModel[view.model.cid] = viewCid; - } - - // index it by collection - if (view.collection){ - this._indexByCollection[view.collection.cid] = viewCid; - } - - // index by custom - if (customIndex){ - this._indexByCustom[customIndex] = viewCid; - } - - this._updateLength(); - }, - - // Find a view by the model that was attached to - // it. Uses the model's `cid` to find it, and - // retrieves the view by it's `cid` from the result - findByModel: function(model){ - var viewCid = this._indexByModel[model.cid]; - return this.findByCid(viewCid); - }, - - // Find a view by the collection that was attached to - // it. Uses the collection's `cid` to find it, and - // retrieves the view by it's `cid` from the result - findByCollection: function(col){ - var viewCid = this._indexByCollection[col.cid]; - return this.findByCid(viewCid); - }, - - // Find a view by a custom indexer. - findByCustom: function(index){ - var viewCid = this._indexByCustom[index]; - return this.findByCid(viewCid); - }, - - // Find by index. This is not guaranteed to be a - // stable index. - findByIndex: function(index){ - return _.values(this._views)[index]; - }, - - // retrieve a view by it's `cid` directly - findByCid: function(cid){ - return this._views[cid]; - }, - - // Remove a view - remove: function(view){ - var viewCid = view.cid; - - // delete model index - if (view.model){ - delete this._indexByModel[view.model.cid]; - } - - // delete collection index - if (view.collection){ - delete this._indexByCollection[view.collection.cid]; - } - - // delete custom index - var cust; - - for (var key in this._indexByCustom){ - if (this._indexByCustom.hasOwnProperty(key)){ - if (this._indexByCustom[key] === viewCid){ - cust = key; - break; - } - } - } - - if (cust){ - delete this._indexByCustom[cust]; - } - - // remove the view from the container - delete this._views[viewCid]; - - // update the length - this._updateLength(); - }, - - // Call a method on every view in the container, - // passing parameters to the call method one at a - // time, like `function.call`. - call: function(method, args){ - args = Array.prototype.slice.call(arguments, 1); - this.apply(method, args); - }, - - // Apply a method on every view in the container, - // passing parameters to the call method one at a - // time, like `function.apply`. - apply: function(method, args){ - var view; - - // fix for IE < 9 - args = args || []; - - _.each(this._views, function(view, key){ - if (_.isFunction(view[method])){ - view[method].apply(view, args); - } - }); - - }, - - // Update the `.length` attribute on this container - _updateLength: function(){ - this.length = _.size(this._views); - }, - - // set up an initial list of views - _addInitialViews: function(views){ - if (!views){ return; } - - var view, i, - length = views.length; - - for (i=0; i */function( window, document, undefined ) { + +(function( factory ) { + "use strict"; + + // Define as an AMD module if possible + if ( typeof define === 'function' && define.amd ) + { + define( ['jquery'], factory ); + } + /* Define using browser globals otherwise + * Prevent multiple instantiations if the script is loaded twice + */ + else if ( jQuery && !jQuery.fn.dataTable ) + { + factory( jQuery ); + } +} +(/** @lends */function( $ ) { + "use strict"; + /** + * DataTables is a plug-in for the jQuery Javascript library. It is a + * highly flexible tool, based upon the foundations of progressive + * enhancement, which will add advanced interaction controls to any + * HTML table. For a full list of features please refer to + * DataTables.net. + * + * Note that the DataTable object is not a global variable but is + * aliased to jQuery.fn.DataTable and jQuery.fn.dataTable through which + * it may be accessed. + * + * @class + * @param {object} [oInit={}] Configuration object for DataTables. Options + * are defined by {@link DataTable.defaults} + * @requires jQuery 1.3+ + * + * @example + * // Basic initialisation + * $(document).ready( function { + * $('#example').dataTable(); + * } ); + * + * @example + * // Initialisation with configuration options - in this case, disable + * // pagination and sorting. + * $(document).ready( function { + * $('#example').dataTable( { + * "bPaginate": false, + * "bSort": false + * } ); + * } ); + */ + var DataTable = function( oInit ) + { + + + /** + * Add a column to the list used for the table with default values + * @param {object} oSettings dataTables settings object + * @param {node} nTh The th element for this column + * @memberof DataTable#oApi + */ + function _fnAddColumn( oSettings, nTh ) + { + var oDefaults = DataTable.defaults.columns; + var iCol = oSettings.aoColumns.length; + var oCol = $.extend( {}, DataTable.models.oColumn, oDefaults, { + "sSortingClass": oSettings.oClasses.sSortable, + "sSortingClassJUI": oSettings.oClasses.sSortJUI, + "nTh": nTh ? nTh : document.createElement('th'), + "sTitle": oDefaults.sTitle ? oDefaults.sTitle : nTh ? nTh.innerHTML : '', + "aDataSort": oDefaults.aDataSort ? oDefaults.aDataSort : [iCol], + "mData": oDefaults.mData ? oDefaults.oDefaults : iCol + } ); + oSettings.aoColumns.push( oCol ); + + /* Add a column specific filter */ + if ( oSettings.aoPreSearchCols[ iCol ] === undefined || oSettings.aoPreSearchCols[ iCol ] === null ) + { + oSettings.aoPreSearchCols[ iCol ] = $.extend( {}, DataTable.models.oSearch ); + } + else + { + var oPre = oSettings.aoPreSearchCols[ iCol ]; + + /* Don't require that the user must specify bRegex, bSmart or bCaseInsensitive */ + if ( oPre.bRegex === undefined ) + { + oPre.bRegex = true; + } + + if ( oPre.bSmart === undefined ) + { + oPre.bSmart = true; + } + + if ( oPre.bCaseInsensitive === undefined ) + { + oPre.bCaseInsensitive = true; + } + } + + /* Use the column options function to initialise classes etc */ + _fnColumnOptions( oSettings, iCol, null ); + } + + + /** + * Apply options for a column + * @param {object} oSettings dataTables settings object + * @param {int} iCol column index to consider + * @param {object} oOptions object with sType, bVisible and bSearchable etc + * @memberof DataTable#oApi + */ + function _fnColumnOptions( oSettings, iCol, oOptions ) + { + var oCol = oSettings.aoColumns[ iCol ]; + + /* User specified column options */ + if ( oOptions !== undefined && oOptions !== null ) + { + /* Backwards compatibility for mDataProp */ + if ( oOptions.mDataProp && !oOptions.mData ) + { + oOptions.mData = oOptions.mDataProp; + } + + if ( oOptions.sType !== undefined ) + { + oCol.sType = oOptions.sType; + oCol._bAutoType = false; + } + + $.extend( oCol, oOptions ); + _fnMap( oCol, oOptions, "sWidth", "sWidthOrig" ); + + /* iDataSort to be applied (backwards compatibility), but aDataSort will take + * priority if defined + */ + if ( oOptions.iDataSort !== undefined ) + { + oCol.aDataSort = [ oOptions.iDataSort ]; + } + _fnMap( oCol, oOptions, "aDataSort" ); + } + + /* Cache the data get and set functions for speed */ + var mRender = oCol.mRender ? _fnGetObjectDataFn( oCol.mRender ) : null; + var mData = _fnGetObjectDataFn( oCol.mData ); + + oCol.fnGetData = function (oData, sSpecific) { + var innerData = mData( oData, sSpecific ); + + if ( oCol.mRender && (sSpecific && sSpecific !== '') ) + { + return mRender( innerData, sSpecific, oData ); + } + return innerData; + }; + oCol.fnSetData = _fnSetObjectDataFn( oCol.mData ); + + /* Feature sorting overrides column specific when off */ + if ( !oSettings.oFeatures.bSort ) + { + oCol.bSortable = false; + } + + /* Check that the class assignment is correct for sorting */ + if ( !oCol.bSortable || + ($.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1) ) + { + oCol.sSortingClass = oSettings.oClasses.sSortableNone; + oCol.sSortingClassJUI = ""; + } + else if ( $.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) == -1 ) + { + oCol.sSortingClass = oSettings.oClasses.sSortable; + oCol.sSortingClassJUI = oSettings.oClasses.sSortJUI; + } + else if ( $.inArray('asc', oCol.asSorting) != -1 && $.inArray('desc', oCol.asSorting) == -1 ) + { + oCol.sSortingClass = oSettings.oClasses.sSortableAsc; + oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIAscAllowed; + } + else if ( $.inArray('asc', oCol.asSorting) == -1 && $.inArray('desc', oCol.asSorting) != -1 ) + { + oCol.sSortingClass = oSettings.oClasses.sSortableDesc; + oCol.sSortingClassJUI = oSettings.oClasses.sSortJUIDescAllowed; + } + } + + + /** + * Adjust the table column widths for new data. Note: you would probably want to + * do a redraw after calling this function! + * @param {object} oSettings dataTables settings object + * @memberof DataTable#oApi + */ + function _fnAdjustColumnSizing ( oSettings ) + { + /* Not interested in doing column width calculation if auto-width is disabled */ + if ( oSettings.oFeatures.bAutoWidth === false ) + { + return false; + } + + _fnCalculateColumnWidths( oSettings ); + for ( var i=0 , iLen=oSettings.aoColumns.length ; i