export default Ember.ObjectController.extend({ breadCrumb: 'Report', // TODO: this is duplicated with submission/index.js assessments: function() { var id = this.get('id'); return this.store.filter('assessment', { submission_id: id }, function(assessment) { return assessment.get('submission.id') === id; }); }.property('id'), publishedAssessments: Ember.computed.filterBy('assessments', 'published', true), rawAverageScore: Ember.reduceComputed('publishedAssessments', { initialValue: 0, initialize: function(initialValue, changeMeta, instanceMeta) { instanceMeta.count = 0; }, addedItem: function(accumulatedValue, item, changeMeta, instanceMeta) { var score = item.get('score'); var avg = cumulativeMovingAverage(accumulatedValue, score, instanceMeta.count); instanceMeta.count++; return avg; }, removedItem: function(accumulatedValue, item, changeMeta, instanceMeta) { var score = item.get('score'); var avg = cumulativeMovingAverage(accumulatedValue, score, instanceMeta.count, true); instanceMeta.count--; return avg; } }), averageScore: function() { return Math.round(this.get('rawAverageScore')); }.property('rawAverageScore'), averageScoreText: function() { return Score.pluralDisplayTextForScore(this.get('averageScore')); }.property('averageScore'), assessors: '', report: '', updateAssessors: function() { var assessments = this.get('publishedAssessments'); var assessors = assessments.map(function(assessment) { return assessment.get('assessor.name') + ' (' + Score.shortDisplayTextForScore(assessment.get('score')) + ')'; }); this.set('assessors', assessors.join(', ')); }.observes('publishedAssessments.[]'), updateReport: function() { var assessments = this.get('publishedAssessments'); var report = assessments.reduce(function(previousValue, item, index) { if (previousValue !== '') { previousValue += '\n\n'; } return previousValue + '##### Developer ' + (index + 1) + ' wrote:\n\n' + '\n\n**Pros:**\n\n' + item.get('pros') + '\n\n**Cons:**\n\n' + item.get('cons') + '\n\n**Notes:**\n\n' + item.get('notes'); }, ''); var renderer = new marked.Renderer(); report = marked(report, { renderer: renderer }); this.set('report', report); }.observes('publishedAssessments.[]') });
import Ember from 'ember'; var DynamoController = Ember.ObjectController.extend({ colors: ['red', 'yellow', 'green', 'orange', 'grellow', 'blood-red', 'out'], actions: { saveColor: function(){ var color = this.get('newColor'); var dynamo = this.store.update('dynamo', { id: this.get('id'), color: color }); dynamo.save(); }, editNote: function(){ this.set('isEditing', true); }, acceptChanges: function(){ this.set('isEditing', false); this.get('model').save(); } } }); export default DynamoController;
// TODO: not DRY (see application.js) export default Ember.ObjectController.extend({ // Requires the sessions and products controllers needs: ['sessions', 'products'], isEditing: Ember.computed.alias('controllers.products.isEditing'), isAdmin: (function() { var res = this.get('controllers.sessions.currentUser.is_admin'); console.log('ProductIndexController: isAdmin => '+res); return res; }).property('controllers.sessions.currentUser'), actions: { editProduct: function(product) { this.set('isEditing', true); this.transitionToRoute('product.edit', product); }, deleteProduct: function(product) { var id = product.get('id'), name = product.get('name'); if (confirm('Are you sure you want to delete product '+name+' (id='+id+') ?')) { console.log('ProductIndexController: Delete product => '+name); product.destroyRecord(); // => DELETE to /products/id } else { console.log('ProductIndexController: Delete product => cancelled'); } this.transitionToRoute('products'); } } });
export default Ember.ObjectController.extend(NewHost, { regionChoices: regionChoices, sizeChoices: function() { var slug = this.get('digitaloceanConfig.region'); return Regions.regions.filter(function(choice) { return choice.slug === slug; })[0].sizes.sort(function(a,b) { var aMb = a.indexOf('mb') >= 0; var bMb = b.indexOf('mb') >= 0; if ( aMb === bMb ) { return parseInt(a,10) - parseInt(b,10); } else if ( aMb ) { return -1; } else { return 1; } }); }.property('digitaloceanConfig.region'), imageChoices: [ // 'coreos-stable', // 'coreos-alpha', // 'coreos-beta', // 'centos-7-0-x64', // 'debian-7-0-x64', // 'fedora-21-x64', 'ubuntu-14-04-x64', 'ubuntu-14-10-x64', ], validate: function() { this._super(); var errors = this.get('errors')||[]; var name = this.get('name')||''; if ( name.length > 200 ) { errors.push('"name" should be 1-200 characters long'); } if ( name.match(/[^a-z0-9-]/i) ) { errors.push('"name" can only contain letters, numbers, and hyphen'); } var accessToken = this.get('digitaloceanConfig.accessToken')||''; if ( accessToken && accessToken.length !== 64 ) { errors.push("That doesn't look like a valid access token"); } if ( errors.get('length') ) { this.set('errors',errors); return false; } return true; }, doneSaving: function() { var out = this._super(); this.transitionToRoute('hosts'); return out; }, });
import Ember from "ember"; export default Ember.ObjectController.extend({ });
export default Ember.ObjectController.extend({ hasQuantity: Ember.computed.mapBy('model','quantity'), count: Ember.computed.sum('hasQuantity'), hasSubtotal: Ember.computed.mapBy('model','subtotal'), subTotal: Ember.computed.sum('hasSubtotal'), actions: { showCartSummary: function(){ //TODO: jquery show var view = Ember.$('.checkout_summary'); //if(view.get('')) view.toggle(); }, showSocialLinks: function(){ //TODO: jquery show var view = Ember.$('.social_links'); //if(view.get('')) view.toggle(); }, removeItem: function(){ //console.log(item.get('title')); this.set('quantity',0); var item = this.get('model'); item.deleteRecord(); item.save(); }, acceptChanges:function(){ //this.set('isEditing', false); if (this.get('model.quantity') < 1){ this.send('removeItem'); } else { this.get('model').save(); } //console.log(this.value);//this.get('value') }, } });
export default Ember.ObjectController.extend(HasCurrentUser, { commentStory: Ember.computed.equal('model.type', 'comment'), mediaStory: Ember.computed.equal('model.type', 'media_story'), followedStory: Ember.computed.equal('model.type', 'followed'), knownStory: Ember.computed.any('commentStory', 'mediaStory', 'followedStory'), unknownStory: Ember.computed.not('knownStory'), substories: Ember.computed.any('allSubstories', 'model.substories'), selfPost: propertyEqual('model.poster.id', 'model.user.id'), moreThanTwoSubstories: Ember.computed.gt('model.substoryCount', 2), isExpanded: false, overflowing: false, showMoreText: 'Show More', showAll: false, loadingAll: false, loadedAll: propertyEqual('substories.length', 'model.substoryCount'), extraLikers: function() { return this.get('totalVotes') - this.get('recentLikers.length'); }.property('totalVotes', 'recentLikers.length'), showExtraLikers: Ember.computed.gt('extraLikers', 0), mediaRoute: function() { return this.get('model.media').constructor.typeKey; }.property('model.media'), displaySubstories: function () { var sorted = this.get('substories').sortBy('createdAt').reverse(); if (sorted.length > 2 && !this.get('showAll')) { return sorted.slice(0, 2); } else { return sorted; } }.property('substories.@each', 'showAll'), reversedDisplaySubstories: function() { return this.get('displaySubstories').reverse(); }.property('displaySubstories.@each'), actions: { submitReply: function() { if (this.get('reply').replace(/\s/g, '').replace(/\[[a-z]+\](.?)\[\/[a-z]+\]/i, '$1').length === 0) { return; } var self = this; this.store.find('user', this.get('currentUser.id')).then(function(user) { var reply = self.store.createRecord('substory', { story: self.get('model'), user: user, type: "reply", reply: self.get('reply'), createdAt: new Date() }); reply.save(); self.incrementProperty('substoryCount'); self.get('substories').addObject(reply); self.set('reply', ''); }); }, toggleShowAll: function () { var self = this; if (!this.get('loadedAll')) { if (!this.get('loadingAll')) { // Load all substories for this story. this.store.find('substory', {story_id: this.get('model.id')}).then(function(substories) { self.set('allSubstories', substories); self.set('loadingAll', false); }); } this.set('loadingAll', true); } return this.set('showAll', !this.get('showAll')); }, deleteStory: function() { this.get('model').destroyRecord(); }, deleteSubstory: function(substory) { var self = this; substory.destroyRecord().then(function() { self.get('model.substories').removeObject(substory); self.decrementProperty('substoryCount'); }); }, toggleFullPost: function() { this.set('isExpanded', !this.get('isExpanded')); if (this.get('isExpanded')) { this.set('showMoreText', 'Show Less'); } else { this.set('showMoreText', 'Show More'); } }, toggleLike: function() { var self = this; this.toggleProperty('isLiked'); Messenger().expectPromise(function() { return self.get('content').save(); }, { progressMessage: function() { if (self.get('isLiked')) { return "Liking post..."; } else { return "Unliking post..."; } }, successMessage: function() { if (self.get('isLiked')) { return "Liked!"; } else { return "Unliked."; } }, errorMessage: "Something went wrong." }); } } });
import Ember from 'ember'; export default Ember.ObjectController.extend({ actions: { addTag: function() { this.parentController.get('selectedTags').pushObject(this); } } });
import Ember from 'ember'; export default Ember.ObjectController.extend(Ember.Validations.Mixin, { validations: { title: { length: { minimum: 15, maximum: 150 } }, body: { length: { minimum: 30, maximum: 10000 } } } });
import Ember from "ember"; const { computed } = Ember; const { oneWay } = computed; export default Ember.ObjectController.extend({ needs: ['model-types'], modelTypes: oneWay('controllers.model-types').readOnly(), selected: computed('modelTypes.selected', function() { return this.get('model') === this.get('modelTypes.selected'); }) });
export default Ember.ObjectController.extend({ actions: { editTodo: function() { this.set('is_editing', true); }, acceptChanges: function() { this.set('is_editing', false); if (Ember.isEmpty(this.get('model.title'))) { this.send('removeTodo'); } else { this.get('model').save(); } }, removeTodo: function() { var model = this.get('model'); model.deleteRecord(); model.save(); } }, is_editing: false, is_completed: function(key, value) { var model = this.get('model'); if (value === undefined) { // Getter return model.get('is_completed'); } else { // Setter // Save the model model.set('is_completed', value); model.save(); // Return the value so the UI stays up to date return value; } }.property('model.is_completed') });
export default Ember.ObjectController.extend(EmberValidations.Mixin, { actions: { save: function() { // redirect to CreateOptions this.transitionToRoute('create.options'); }, submit: function(){ this.validate(); Ember.$.each(Ember.View.views, function(id, view) { if(view.isEasyForm) { view.focusOut(); } }); if (this.get('isValid')) { this.send('save'); } } }, validations: { title: { presence: true, length: { minimum: 2 } } } });
import Ember from "ember"; import ENV from "../../../config/environment"; import handleModelError from '../../../utils/handle-model-error'; export default Ember.ObjectController.extend({ breadCrumb: {name: 'File Sync', icon: 'refresh'}, actions: { saveSettings: function() { var self = this, config = this.get('model.config'); Ember.$.ajax(`${ENV.APP.krakenHost}/api/apps/syncthing/config`, { type: 'POST', data: JSON.stringify({config: config}), contentType: 'application/json' }) .done(function() { self.notifications.new("success", "Configuration saved successfully"); }) .fail(function(e) { handleModelError(self, e); }); } } });
import Ember from "ember"; export default Ember.ObjectController.extend({ weekdays: [null, "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday", "Sunday"], localDayOfTheWeek: function () { return this.get("weekdays")[this.get("local_day_of_the_week")]; }.property("local_day_of_the_week") });
import Ember from 'ember'; export default Ember.ObjectController.extend({ needs: ['reveal'], actions: { openModal: function(content) { var reveal = this.get('controllers.reveal'); reveal.set('content', content); reveal.set('reveal', true); } } });
import Ember from 'ember'; export default Ember.ObjectController.extend({ myData: function(){ var data = []; var i; for(i = 0; i < 20; i++) { data.push({ id: i + 1, name: 'Item ' + i, number: Math.round((Math.random() * 200) - 100) }); } return data; }.property(), actions: { incrementNumber: function(row) { var current = Ember.get(row, 'number'); Ember.set(row, 'number', current + 1); }, }, });
export default Ember.ObjectController.extend({ // Requires the sessions controller needs: ['sessions', 'users'], isEditing: Ember.computed.alias('controllers.users.isEditing'), readOnly: Ember.computed.alias('controllers.users.readOnly'), isAdmin: (function() { var res = this.get('controllers.sessions.currentUser.is_admin'); console.log('UserEditController: isAdmin => '+res); return res; }).property('controllers.sessions.currentUser'), actions: { saveEditUser: function (user) { console.log('UserEditController: save edit user'); if (this.controllerFor('users').validUser(user, true)) { user.save(); this.set('isEditing', false); this.transitionToRoute('user', user); } else { return false; } }, cancelEditUser: function (user) { console.log('UserEditController: cancel edit user'); user.rollback(); this.set('isEditing', false); this.transitionToRoute('users'); } } });
import Ember from "ember"; export default Ember.ObjectController.extend({ actions: { login: function() { var user = this.get('model'), password = user.get('password'); user.login().then((data)=> { this.get('session').login(data, password); // Will be true if the user was directed to log in from a // route requiring authorization. var requestedTransition = this.get('session.requestedTransition'); if(requestedTransition) { requestedTransition.retry(); } else { this.transitionToRoute('index'); } }, function() { /* We must at least catch the error to prevent it from bubbling up to the console. */ }); } } });
import Ember from "ember"; export default Ember.ObjectController.extend({ needs: ['page/section', 'page'] });
import Ember from 'ember'; import stringifyCSS from 'krafty-kai/utils/stringify-css'; export default Ember.ObjectController.extend({ joinedDate: function() { return stringifyCSS({ "font-size": "0.4em" }); }.property(), authorTitle: function() { return stringifyCSS({ "margin-top": "0", "font-size": "1.5em" }); }.property(), authorName: function() { return stringifyCSS({ "margin-bottom": "5px" }); }.property() });
import Ember from 'ember'; export default Ember.ObjectController.extend({ actions: { save: function () { var series = this.get('model') series = this.store.createRecord('series', { title: series.title, volume: series.volume }) var transitionToSeries = function (series) { console.log(series) this.transitionToRoute('series.show', series) }.bind(this) var failure = function (err) { console.log(err) } series.save().then(transitionToSeries).catch(failure) } } });
export default Ember.ObjectController.extend({ needs: ['todos'], isCompleted: function(key, value){ var model = this.get('model'); if (arguments.length === 2) { // property being used as a setter model.set('isCompleted', value); model.save(); return value; } else { // property being used as a getter return model.get('isCompleted'); } }.property('model.isCompleted'), _onlyOneActive: equal('controllers.todos.active.length', 1), _isNotCompleted: not('isCompleted'), isLastRemaining: and('_isNotCompleted', '_onlyOneActive'), isEditing: false, actions: { editTodo: function () { this.set('isEditing', true); }, removeTodo: function () { var todo = this.get('model'); todo.deleteRecord(); todo.save(); }, acceptChanges: function () { this.set('isEditing', false); this.get('model').save(); } } });
export default Ember.ObjectController.extend(EmberValidations, { name: '', telephone: '', sponsor: '', isNoSponsor: false, isShowing: false, validations: { telephone: { presence: true, numericality: true, length: 11 } }, optionsHost: function () { return { all: ['163.com', '126.com', 'yeah.com'], selected: '163.com' }; }.property(), optionsPinyin: function () { return { all: [ {name: this.t('tools.account.base.setting.options_pinyin.all'), id: 1}, {name: this.t('tools.account.base.setting.options_pinyin.first'), id: 2}], selected: 1 }; }.property(), optionsLetter: function () { return { all: [ {name: this.t('tools.account.base.setting.options_letter.capitalize'), id: 1}, {name: this.t('tools.account.base.setting.options_letter.uppercase'), id: 2}], selected: 1 }; }.property(), optionsDigital: function () { return { all: [ {name: this.t('tools.account.base.setting.options_digital.last8'), id: 1}, {name: this.t('tools.account.base.setting.options_digital.last4'), id: 2}, {name: this.t('tools.account.base.setting.options_digital.center'), id: 3}, {name: this.t('tools.account.base.setting.options_digital.random'), id: 4}], selected: 1 }; }.property(), //类型:简拼还是全拼 用于帐号设置 pinyinStyle: function () { var option = this.get('optionsPinyin.selected'); var result = {}; switch (option) { case 1: result.style = pinyin.STYLE_NORMAL; // 设置拼音风格 `中心` [ [ 'zhong' ], [ 'xin' ] ]); break; case 2: result.style = pinyin.STYLE_FIRST_LETTER; // 设置拼音风格 `中心` [ [ 'z' ], [ 'x' ] ]); break; } return result; }.property('optionsPinyin.selected'), //字母:大写还是小写 用于密码混合 pinyinLetter: function () { var option = this.get('optionsLetter.selected'); var letter = ''; switch (option) { case 1: letter = this.get('pinyinOfName').capitalize(); //首字母大写 break; case 2: letter = this.get('pinyinOfName').toUpperCase(); break; } return letter; }.property('pinyinOfName', 'optionsLetter.selected'), //数字:中间或最后的4位 用于密码混合 pinyinDigital: function () { var option = this.get('optionsDigital.selected'); var digital = ''; switch (option) { case 1: digital = this.get('telephone').substr(3, 8); //末尾8位 break; case 2: digital = this.get('telephone').substr(7, 4);//末尾4位 break; case 3: digital = this.get('telephone').substr(2, 4);//中间4位 break; case 4: digital = Math.floor(Math.random()*1000000+1);//随机产生 break; } return digital; }.property('telephone', 'optionsDigital.selected'), pinyinOfName: function () { var nameArray = pinyin(this.get('name'), this.get('pinyinStyle')); var name = ''; nameArray.forEach(function (n) { name += n[0]; }); return name; }.property('name', 'pinyinStyle'), emailAccount: function () { return this.get('pinyinOfName'); }.property('pinyinOfName'), onecoinAccount: function () { var email = ''; if (this.get('emailAccount') !== '') { email = this.get('emailAccount') + '@' + this.get('optionsHost.selected'); } return email; }.property('emailAccount', 'optionsHost.selected'), onepayAccount: function () { return this.get('onecoinAccount'); }.property('onecoinAccount'), //密码设置 emailPassword: function () { return this.get('pinyinLetter') + this.get('pinyinDigital'); }.property('pinyinLetter', 'pinyinDigital'), onecoinPasswordBinding: 'emailPassword', onepayPasswordBinding: 'emailPassword', onecoinSignupUrl: function () { var url = "http://onecoin.eu/signup/"; if (this.get('isNoSponsor')) { url += "onecoinjr"; } else { url += this.get('sponsor'); } return url; }.property('sponsor', 'isNoSponsor'), clickNoSponsor: function () { var txt = this.t('tools.account.click_here'); if (this.get('isNoSponsor')) { txt = this.t('tools.account.onecoin.clicknosponsor'); } return txt; }.property('sponsor', 'isNoSponsor'), showClickMe: function () { if (this.get('isNoSponsor') || this.get('sponsor').length > 0) { this.set('isShowing', true); } else { this.set('isShowing', false); } }.observes('sponsor', 'isNoSponsor'), actions: { download: function () { // fixme pdfMake对文本的格式化很好,相当于独立建立了一套doc解析;但无法直接从html生成,姑且放弃。 // var docDefinition = { content: 'This is an sample PDF printed with pdfMake 你好,我来了' }; //pdfMake.createPdf(docDefinition).download(); // todo jsPDF 通过插件的方式扩展,提供了fromHtml,addHtml(使用第三方获得对encode的支持)方法,但是无法支持encode编码 //var doc = new jsPDF('p', 'pt', 'a4'); ////var specialElementHandlers = { //// '.bypass': function (element, renderer) { //// return true; //// } ////}; //doc.addHTML($('#jspdf')[0]); //var save = doc.save(this.get('name') + '.pdf'); //setTimeout("save",5); } } });
import Ember from 'ember'; export default Ember.ObjectController.extend({ needs: ['friends-graph'], navLinks: function () { return [ { name: 'Friends Graph', route: 'friends-graph.index' }, { name: 'New', route: 'posts.new' }, { name: 'Index', route: 'posts.index' } ] }.property(), leftSidebarClass: 'friends-graph', setupDefaultShownConnection: function () { this.set('controllers.friends-graph.defaultShownConnection', this.get('content')); } });
var ResourceController = Ember.ObjectController.extend({ needs: ['application','authenticated'], actions: { goToApi: function() { var url = this.get('links.self'); // http://a.b.c.d/v1/things/id, a.b.c.d is where the UI is running var endpoint = this.get('controllers.application.absoluteEndpoint'); // http://e.f.g.h/ , does not include version. e.f.g.h is where the API actually is. url = url.replace(/https?:\/\/[^\/]+\/?/,endpoint); if ( this.get('app.authenticationEnabled') ) { url = Util.addAuthorization(url, C.HEADER.AUTH_FAKE_USER +'=' + this.get('session.'+C.SESSION.PROJECT), this.get('session.'+C.SESSION.TOKEN)); } window.open(url, '_blank'); }, }, displayName: function() { return this.get('name') || '('+this.get('id')+')'; }.property('name','id'), isDeleted: Ember.computed.equal('state','removed'), isPurged: Ember.computed.equal('state','purged'), hasAction: modelProxy('hasAction'), doAction: modelProxy('doAction'), linkFor: modelProxy('linkFor'), hasLink: modelProxy('hasLink'), importLink: modelProxy('importLink'), followLink: modelProxy('followLink'), save: modelProxy('save'), delete: modelProxy('delete'), reload: modelProxy('reload'), isInStore: modelProxy('isInStore'), availableActions: function() { /* Override me and return [ { enabled: true/false, // Whether it's enabled or greyed out detail: true/false, // If true, this action will only be shown on detailed screens label: 'Delete', // Label shown on hover or in menu icon: 'fa-trash-o', // Icon shown on screen action: 'promptDelete', // Action to call on the controller when clicked altAction: 'delete' // Action to call on the controller when alt+clicked divider: true, // Just this will make a divider }, ... ] */ return []; }, });
export default Ember.ObjectController.extend({ needs: ["user"], userBinding: "controllers.user", commentsBadge: function(){ return this.get("comments.length") || this.get("commentCount"); }.property("comments.length"), actions: { createComment: function(text){ var controller = this; var newComment = this.store.createRecord("comment", { text: text, card: this.get("model"), creator: this.get("user.model") }); newComment.save() .then( function(comment){ return controller.get("comments") .then(function(comments){ comments.unshiftObject(comment); controller.send("resetCommentForm"); }); } ); }, deleteComment: function(comment){ var controller = this; var cardId = this.get("id"); var commentId = comment.id; Trello.delete("/cards/" + cardId + "/actions/" + commentId + "/comments", function(response){ console.log("comment delete success", response); controller.get("comments").removeObject(comment); }, function(response){ console.log("comment delete failure", response); } ); } } });
var DashboardController = Ember.ObjectController.extend({ search: '', jsonBody: '', githubRootURL: "https://api.github.com/users/", starredJSON: '', getJSON: function(url) { var result = Ember.Object.create({content: null, isLoaded: false}); Ember.$.ajax({ url: url, dataType: 'json', success: function(data) { result.setProperties(data); result.set('isLoaded', true); }, error: function() { return console.log("couldnt find user name"); } }); this.set('jsonBody', result); console.log(this.get('jsonBody')); }, getStarred: function(url) { var result = Ember.Object.create({content: null, isLoaded: false}); Ember.$.ajax({ url: url, dataType: 'json', success: function(data) { result.setProperties(data); result.set('isLoaded', true); }, error: function() { return console.log("couldnt find user name"); } }); this.set('starredJSON', result); console.log(this.get('starredJSON')); }, actions: { query: function() { var username = this.get('search'); var url = this.githubRootURL + username; this.getJSON(url); this.set('search', ''); }, starred: function() { var url = this.get('jsonBody').url + "/starred"; this.getStarred(url); } } });
import Ember from 'ember'; export default Ember.ObjectController.extend({ actions: { submit: function() { var review = this.model; review.save().then(function() { // nothing here... }, function() { review.deleteRecord(); }); }, like: function() { this.set('like', true); }, dislike: function() { this.set('like', false); } } });
import Ember from 'ember'; import Cattle from 'ui/utils/cattle'; import EditLabels from 'ui/mixins/edit-labels'; export default Ember.ObjectController.extend(Cattle.NewOrEditMixin, EditLabels, { editing: true, doneSaving: function() { this.send('goToPrevious'); } });
default Ember.ObjectController.extend({ needs: ['photos'], photos: Ember.computed.alias('controllers.photos'), hasPrevious: false, hasNext: false, photoSource: function() { return 'assets/albums/' + this.get('album.name') + '/' + this.get('source'); }.property('source'), actions: { /* * Exit full screen mode and goes back to photos route. * * @action 'exitFullScreenMode' */ exitFullScreenMode: function() { this.transitionToRoute('photos'); }, /* * Show next photo in the album. * * @action 'showNext' */ showNext: function() { var currentIndex = this.get('photos.model').indexOf(this.get('model')), nextPhoto = this.get('photos.model').objectAt(currentIndex + 1); this.transitionToRoute('photo', nextPhoto); }, /* * Show previous photo in the album. * * @action 'showPrevious' */ showPrevious: function() { var currentIndex = this.get('photos.model').indexOf(this.get('model')), previousPhoto = this.get('photos.model').objectAt(currentIndex - 1); this.transitionToRoute('photo', previousPhoto); } } });