From a2e31088b5c79acdd783d2b41575ddf084f02685 Mon Sep 17 00:00:00 2001 From: "Omar S." Date: Sun, 28 Dec 2014 23:07:59 -0500 Subject: [PATCH 1/7] Added just one thing at the start If you don't like it, don't do this, but there should be a thing that tells beginners to start there --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 1260913ca..35ac7bb4d 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ CodeCombat ![](https://dl.dropboxusercontent.com/u/138899/GitHub%20Wikis/readme_00.png) [![Build Status](https://travis-ci.org/codecombat/codecombat.png?branch=master)](https://travis-ci.org/codecombat/codecombat) -CodeCombat is a multiplayer programming game for learning how to code. **See the [Archmage developer wiki](https://github.com/codecombat/codecombat/wiki/Archmage-Home) for a dev setup guide, extensive documentation, and much more.** +CodeCombat is a multiplayer programming game for learning how to code. **See the [Archmage (coder) developer wiki](https://github.com/codecombat/codecombat/wiki/Archmage-Home) for a dev setup guide, extensive documentation, and much more. Every new person that wants to start contributing the project coding should start there** It's both a startup and a community project, completely open source under the [MIT and Creative Commons licenses](http://codecombat.com/legal). It's the largest open source [CoffeeScript](http://coffeescript.org/) project by lines of code, and since it's a game (with [really cool tech](https://github.com/codecombat/codecombat/wiki/Third-party-software-and-services)), it's really fun to hack on. Join us in teaching the world to code! Your contribution will go on to show millions of players how cool programming can be. From 0c43b21078f4cf25639e6a3fdfb8b5b7b80c2331 Mon Sep 17 00:00:00 2001 From: Ivan Milanov Date: Mon, 29 Dec 2014 14:33:06 +0100 Subject: [PATCH 2/7] Added more translations --- app/locale/mk-MK.coffee | 128 ++++++++++++++++++++-------------------- 1 file changed, 64 insertions(+), 64 deletions(-) diff --git a/app/locale/mk-MK.coffee b/app/locale/mk-MK.coffee index 436895466..fc0a0a12c 100644 --- a/app/locale/mk-MK.coffee +++ b/app/locale/mk-MK.coffee @@ -97,62 +97,62 @@ module.exports = nativeDescription: "Македонски", englishDescription: # campaign_classic_algorithms: "Classic Algorithms" # campaign_classic_algorithms_description: "... in which you learn the most popular algorithms in Computer Science." -# login: -# sign_up: "Create Account" -# log_in: "Log In" -# logging_in: "Logging In" -# log_out: "Log Out" -# forgot_password: "Forgot your password?" -# authenticate_gplus: "Authenticate G+" -# load_profile: "Load G+ Profile" -# load_email: "Load G+ Email" -# finishing: "Finishing" -# sign_in_with_facebook: "Sign in with Facebook" -# sign_in_with_gplus: "Sign in with G+" -# signup_switch: "Want to create an account?" + login: + sign_up: "Направи Сметка" + log_in: "Најави се" + logging_in: "Најавувањето е во тек" + log_out: "Одјави се" + forgot_password: "Ја заборави својата лозинка?" + authenticate_gplus: "Провери G+ најава" + load_profile: "Вчитај G+ Профил" + load_email: "Вчитај G+ Email" + finishing: "Завршување" + sign_in_with_facebook: "Најави се со Facebook" + sign_in_with_gplus: "Најави се со G+" + signup_switch: "Сакаш да направиш сметка?" -# signup: -# email_announcements: "Receive announcements by email" -# creating: "Creating Account..." -# sign_up: "Sign Up" -# log_in: "log in with password" -# social_signup: "Or, you can sign up through Facebook or G+:" -# required: "You need to log in before you can go that way." -# login_switch: "Already have an account?" + signup: + email_announcements: "Примај соопштенија преку email" + creating: "Сметката се прави..." + sign_up: "Направи Сметка" + log_in: "најави се со лозинка" + social_signup: "Или, можеш да се пријавиш преку Facebook или G+:" + required: "Мораш да се најавиш за да имаш пристап таму." + login_switch: "Веќе имаш сметка?" -# recover: -# recover_account_title: "Recover Account" -# send_password: "Send Recovery Password" -# recovery_sent: "Recovery email sent." + recover: + recover_account_title: "Врати Сметка" + send_password: "Испрати лозинка за враќање" + recovery_sent: "Email-от за враќање на лозинката е испратен." -# items: -# primary: "Primary" -# secondary: "Secondary" -# armor: "Armor" -# accessories: "Accessories" -# misc: "Misc" -# books: "Books" + items: + primary: "Главно" + secondary: "Споредно" + armor: "Оклоп" + accessories: "Додатоци" + misc: "Разно" + books: "Книги" -# common: -# loading: "Loading..." -# saving: "Saving..." -# sending: "Sending..." -# send: "Send" -# cancel: "Cancel" -# save: "Save" -# publish: "Publish" -# create: "Create" -# manual: "Manual" + common: + loading: "Вчитување..." + saving: "Зачувување..." + sending: "Испраќање..." + send: "Испрати" + cancel: "Откажи" + save: "Зачувај" + publish: "Објави" + create: "Направи" + manual: "Прирачник" # fork: "Fork" -# play: "Play" # When used as an action verb, like "Play next level" -# retry: "Retry" -# actions: "Actions" -# info: "Info" -# help: "Help" + play: "Играј" # When used as an action verb, like "Play next level" + retry: "Обиди се повторно" + actions: "Дејствија" + info: "Инфо" + help: "Помош" # watch: "Watch" # unwatch: "Unwatch" -# submit_patch: "Submit Patch" -# submit_changes: "Submit Changes" + submit_patch: "Поднеси Закрпа" + submit_changes: "Поднеси Промени" # general: # and: "and" @@ -193,21 +193,21 @@ module.exports = nativeDescription: "Македонски", englishDescription: # player: "Player" # player_level: "Level" # Like player level 5, not like level: Dungeons of Kithgard -# units: -# second: "second" -# seconds: "seconds" -# minute: "minute" -# minutes: "minutes" -# hour: "hour" -# hours: "hours" -# day: "day" -# days: "days" -# week: "week" -# weeks: "weeks" -# month: "month" -# months: "months" -# year: "year" -# years: "years" + units: + second: "секунда" + seconds: "секунди" + minute: "минута" + minutes: "минути" + hour: "час" + hours: "часови" + day: "ден" + days: "денови" + week: "недела" + weeks: "недели" + month: "месец" + months: "месеци" + year: "година" + years: "години" # play_level: # done: "Done" From 3b8fdecc18d058fd29eb65fdb404f0876526cce5 Mon Sep 17 00:00:00 2001 From: Imperadeiro98 Date: Mon, 29 Dec 2014 15:38:26 +0000 Subject: [PATCH 3/7] Fixed a mistake --- app/templates/core/auth.jade | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/templates/core/auth.jade b/app/templates/core/auth.jade index 331cdc8a8..eb2a0571a 100644 --- a/app/templates/core/auth.jade +++ b/app/templates/core/auth.jade @@ -31,7 +31,7 @@ .form-group if mode === 'login' div#recover-account-wrapper - a(data-toggle="coco-modal", data-target="core/RecoverModal", data-i18n="login.forgo_password")#link-to-recover Forgot your password? + a(data-toggle="coco-modal", data-target="core/RecoverModal", data-i18n="login.forgot_password")#link-to-recover Forgot your password? label.control-label(for="password") span(data-i18n="general.password") Password | : From a9875fd19d57223b570ff8534406cc667ce7b680 Mon Sep 17 00:00:00 2001 From: "Omar S." Date: Mon, 29 Dec 2014 10:40:29 -0500 Subject: [PATCH 4/7] More translations Up to 591 + some ones that were missing --- app/locale/es-419.coffee | 68 ++++++++++++++++++++-------------------- 1 file changed, 34 insertions(+), 34 deletions(-) diff --git a/app/locale/es-419.coffee b/app/locale/es-419.coffee index 222c54770..90ad2734a 100644 --- a/app/locale/es-419.coffee +++ b/app/locale/es-419.coffee @@ -146,13 +146,13 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip fork: "Bifurcar" play: "Jugar" # When used as an action verb, like "Play next level" retry: "Reintentar" -# actions: "Actions" -# info: "Info" -# help: "Help" + actions: "Acciones" + info: "Info" + help: "Ayuda" watch: "Seguir" unwatch: "No seguir" submit_patch: "Enviar Parche" -# submit_changes: "Submit Changes" + submit_changes: "Enviar cambios" general: and: "y" @@ -160,16 +160,16 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip date: "Fecha" body: "Cuerpo" version: "Versión" -# submitter: "Submitter" -# submitted: "Submitted" +# submitter: "Submitter" + submitted: "Enviado" commit_msg: "Enviar mensaje" -# review: "Review" + review: "Revisión" version_history: "Historial de Versiones" version_history_for: "Historial de Versiones para: " -# select_changes: "Select two changes below to see the difference." -# undo: "Undo (Ctrl+Z)" -# redo: "Redo (Ctrl+Shift+Z)" -# play_preview: "Play preview of current level" + select_changes: "Selcciona dos cambios abajo para ver la diferencia" + undo: "Deshacer (Ctrl+Z)" + redo: "Volver a hacer (Ctrl+Shift+Z)" + play_preview: "Mira el avance del nivel" result: "Resultado" results: "Resultados" description: "Descripción" @@ -270,7 +270,7 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip loading_ready: "¡Listo!" loading_start: "Iniciar nivel" problem_alert_title: "Revisa tu código" -# problem_alert_help: "Help" + problem_alert_help: "Ayuda" time_current: "Ahora:" time_total: "Max:" time_goto: "Ir a:" @@ -314,7 +314,7 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip save_load_tab: "Guardar/Cargar" options_tab: "Opciones" guide_tab: "Guía" -# guide_video_tutorial: "Video Tutorial" + guide_video_tutorial: "Guía en video" guide_tips: "Pistas" multiplayer_tab: "Multijugador" auth_tab: "Ingresar" @@ -329,7 +329,7 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip inventory: choose_inventory: "Equipar objetos" equipped_item: "Equipado" -# required_purchase_title: "Required" + required_purchase_title: "Requerido" available_item: "Disponible" restricted_title: "Restringido" should_equip: "(doble-click para equipar)" @@ -349,7 +349,7 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip prompt_title: "Gemas insuficientes" prompt_body: "¿Quieres obtener más?" prompt_button: "Entrar al mercado" -# recovered: "Previous gems purchase recovered. Please refresh the page." + recovered: "Se recuperaron las anteriores compras de gemas. Por favor recarga la página" subscribe: subscribe_title: "Suscribirse" @@ -478,18 +478,18 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip contact: contact_us: "Contacta a CodeCombat" - welcome: "¡Qué bueno es escucharte! Usa este formulario para enviarnos un mensaje" + welcome: "¡Qué bueno es escuchar algo de ti! Usa este formulario para enviarnos un mensaje" forum_prefix: "Para cualquier cosa pública, por favor prueba " forum_page: "nuestro foro " forum_suffix: "en su lugar." -# faq_prefix: "There's also a" -# faq: "FAQ" -# subscribe_prefix: "If you need help figuring out a level, please" -# subscribe: "buy a CodeCombat subscription" -# subscribe_suffix: "and we'll be happy to help you with your code." -# subscriber_support: "Since you're a CodeCombat subscriber, your email will get our priority support." + faq_prefix: "También hay un" + faq: "FAQ" + subscribe_prefix: "Si necesitas ayuda para resolver un nivel, por favor" + subscribe: "compra una suscripción de CodeCombat" + subscribe_suffix: "y nosotros estaremos felices de ayudarte con tu código." + subscriber_support: "Como estás suscrito a CodeCombat, tu email tendrá prioridad." # screenshot_included: "Screenshot included." -# where_reply: "Where should we reply?" + where_reply: "¿A dónde deberíamos responder?" send: "Enviar Comentario" contact_candidate: "Contacta un Candidato" # Deprecated recruitment_reminder: "Usa este formulario para llegar a los candidatos que estés interesado en entrevistar. Recuerda que CodeCombat cobra 18% del primer año de salario. Este honorario se debe a la contratación del empleado y reembolsable por 90 días si el empleado no permanece contratado. Tiempo parcial, remoto, y empleados por contrato son gratis, como así también internos." # Deprecated @@ -557,10 +557,10 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip introduction: "Mira las maneras en las que puedes involucrarte adelante y decide qué es más divertido. ¡Queremos trabajar contigo!" level_editor_prefix: "Usar CodeCombat" level_editor_suffix: "para crear y editar niveles. Los han creado niveles para sus clases, amigos, hackatones, estudiantes, familiares. Si crear un nuevo juego luce intimidante puedes ¡comenzar con base en uno nuestro!" -# thang_editor_prefix: "We call units within the game 'thangs'. Use the" -# thang_editor_suffix: "to modify the CodeCombat source artwork. Allow units to throw projectiles, alter the direction of an animation, change a unit's hit points, or upload your own vector sprites." -# article_editor_prefix: "See a mistake in some of our docs? Want to make some instructions for your own creations? Check out the" -# article_editor_suffix: "and help CodeCombat players get the most out of their playtime." + thang_editor_prefix: "Nosotros llamamos a las unidades del juego 'thangs'. Usa el" + thang_editor_suffix: "para modificar el arte de CodeCombat. Permite a las unidades lanzar proyectiles, altera la dirección de una animación, cambia los puntos de vida de una unidad o sube tu propio sprite de vectores." + article_editor_prefix: "¿Ves algún error en nuestros documentos? ¿Quieres hacer algunas instrucciones para tus propias creaciones? Revisa el" + article_editor_suffix: "y ayuda a los jugadores de CodeCombat conseguir lo más posible de su tiempo jugando." find_us: "Encuentranos en etsos sitios" social_blog: "Lee el blog de CodeCombat en Sett" social_discource: "Unite a la discusión en nuestro foro" @@ -573,22 +573,22 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip classes: archmage_title: "Archimago" archmage_title_description: "(Desarrollador)" -# archmage_summary: "If you are a developer interested in coding educational games, become an archmage to help us build CodeCombat!" + archmage_summary: "Si eres un programador interesado en juegos educativos, conviértete en un archimago y ayúdanos a construir CodeCombat!" artisan_title: "Artesano" artisan_title_description: "(Constructor de Niveles)" -# artisan_summary: "Build and share levels for you and your friends to play. Become an Artisan to learn the art of teaching others to program." + artisan_summary: "Construye y comparte niveles para que tú y tus amigos jueguen. Conviértete en un Artesano y aprende el arte the enseñar a los demás a programar." adventurer_title: "Aventurero" adventurer_title_description: "(Probador de Niveles)" -# adventurer_summary: "Get our new levels (even our subscriber content) for free one week early and help us work out bugs before our public release." + adventurer_summary: "Consigue nuestros nuevos niveles| (even our subscriber content) for free one week early and help us work out bugs before our public release." scribe_title: "Escriba" scribe_title_description: "(Editor de Artículos)" -# scribe_summary: "Good code needs good documentation. Write, edit, and improve the docs read by millions of players across the globe." - diplomat_title: "Diplomado" + scribe_summary: "Buen código necesita buena documentación. Escribe, edita y mejora los documentos leídos por millones de jugadores en el mundo." + diplomat_title: "Diplomático" diplomat_title_description: "(Traductor)" -# diplomat_summary: "CodeCombat is localized in 45+ languages by our Diplomats. Help us out and contribute translations." + diplomat_summary: "CodeCombat está traducido a más de 45 idiomas por nuestros diplomáticos. Ayúdanos y contribuye con las traducciones." ambassador_title: "Embajador" ambassador_title_description: "(Soporte)" -# ambassador_summary: "Tame our forum users and provide direction for those with questions. Our ambassadors represent CodeCombat to the world." + ambassador_summary: "Ayuda a responder las preguntas de los usuarios del foro. Nuestros Embajadores representan CodeCombat en todo el mundo." editor: main_title: "Editor de CodeCombat" From d67a329cb9f7f0560ece1ac02753e9f353226abc Mon Sep 17 00:00:00 2001 From: "Omar S." Date: Mon, 29 Dec 2014 10:51:14 -0500 Subject: [PATCH 5/7] Added submitter --- app/locale/es-419.coffee | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/locale/es-419.coffee b/app/locale/es-419.coffee index 90ad2734a..0831fea50 100644 --- a/app/locale/es-419.coffee +++ b/app/locale/es-419.coffee @@ -160,7 +160,7 @@ module.exports = nativeDescription: "Español (América Latina)", englishDescrip date: "Fecha" body: "Cuerpo" version: "Versión" -# submitter: "Submitter" + submitter: "Emisor" #O originador, que dicen? submitted: "Enviado" commit_msg: "Enviar mensaje" review: "Revisión" From d85bf8d59ab4a9a4dc7bbd6dd343163a7ac93b73 Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Mon, 29 Dec 2014 08:45:55 -0800 Subject: [PATCH 6/7] Fixed disabled level logic. --- app/templates/base.jade | 4 ++-- app/templates/play/campaign-view.jade | 2 +- app/views/play/CampaignView.coffee | 9 ++++----- 3 files changed, 7 insertions(+), 8 deletions(-) diff --git a/app/templates/base.jade b/app/templates/base.jade index c8b3848f4..bda7a21dd 100644 --- a/app/templates/base.jade +++ b/app/templates/base.jade @@ -59,7 +59,7 @@ block footer #footer-links a(href='/contribute', tabindex=-1, data-i18n="nav.contribute") Contribute a(href='/legal', tabindex=-1, data-i18n="nav.legal") Legal - a(title='Contact', tabindex=-1, data-toggle="coco-modal", data-target="core/ContactModal", data-i18n="nav.contact") Contact + a(tabindex=-1, data-toggle="coco-modal", data-target="core/ContactModal", data-i18n="nav.contact") Contact a(href='/teachers', data-i18n="nav.teachers") Teachers a(href="/play-old", data-i18n="play.older_campaigns") Older Campaigns if me.isAdmin() @@ -80,7 +80,7 @@ block footer span span © All Rights Reserved br - span CodeCombat 2014 + span CodeCombat 2015 img#footer-logo(src="/images/pages/base/logo.png", alt="CodeCombat") span span Site Design by diff --git a/app/templates/play/campaign-view.jade b/app/templates/play/campaign-view.jade index be29348f2..3466dd238 100644 --- a/app/templates/play/campaign-view.jade +++ b/app/templates/play/campaign-view.jade @@ -7,7 +7,7 @@ each level in levels if !level.hidden - div(style="left: #{level.position.x}%; bottom: #{level.position.y}%; background-color: #{level.color}", class="level" + (level.next ? " next" : "") + (level.disabled ? " disabled" : "") + (level.locked ? " locked" : "") + " " + levelStatusMap[level.slug] || "", data-level-slug=level.slug, title=level.name + (level.disabled ? ' (Coming Soon to Adventurers)' : '')) + div(style="left: #{level.position.x}%; bottom: #{level.position.y}%; background-color: #{level.color}", class="level" + (level.next ? " next" : "") + (level.disabled ? " disabled" : "") + (level.locked ? " locked" : "") + " " + levelStatusMap[level.slug] || "", data-level-slug=level.slug, data-level-original=level.original, title=level.name + (level.disabled ? ' (Coming Soon to Adventurers)' : '')) if level.unlocksHero && !level.unlockedHero img.hero-portrait(src=level.unlocksHero.img) a(href=level.type == 'hero' ? '#' : level.disabled ? "/play" : "/play/#{level.levelPath || 'level'}/#{level.slug}", disabled=level.disabled, data-level-slug=level.slug, data-level-path=level.levelPath || 'level', data-level-name=level.name) diff --git a/app/views/play/CampaignView.coffee b/app/views/play/CampaignView.coffee index 364816c58..27cd0cea7 100644 --- a/app/views/play/CampaignView.coffee +++ b/app/views/play/CampaignView.coffee @@ -136,15 +136,14 @@ module.exports = class CampaignView extends RootView level.position ?= { x: 10, y: 10 } level.locked = not me.ownsLevel level.original level.locked = false if @levelStatusMap[level.slug] in ['started', 'complete'] - level.locked = false if me.get('slug') is 'nick' level.locked = false if @editorMode - level.disabled = true if not me.isAdmin() and level.adminOnly and not @levelStatusMap[level.slug] in ['started', 'complete'] + level.disabled = true if level.adminOnly and @levelStatusMap[level.slug] not in ['started', 'complete'] level.color = 'rgb(255, 80, 60)' if level.requiresSubscription level.color = 'rgb(80, 130, 200)' if level.unlocksHero level.unlockedHero = level.unlocksHero.originalID in (me.get('earned')?.heroes or []) - level.hidden = level.locked or level.disabled + level.hidden = level.locked # put lower levels in last, so in the world map they layer over one another properly. context.campaign.levels = (_.sortBy context.campaign.levels, (l) -> l.position.y).reverse() @@ -181,7 +180,7 @@ module.exports = class CampaignView extends RootView bg = $('.map-background') x = ($(@).offset().left - bg.offset().left + $(@).outerWidth() / 2) / bg.width() y = 1 - ($(@).offset().top - bg.offset().top + $(@).outerHeight() / 2) / bg.height() - e = { position: { x: (100 * x), y: (100 * y) }, levelOriginal: $(@).data('level-slug'), campaignID: $(@).data('campaign-id') } + e = { position: { x: (100 * x), y: (100 * y) }, levelOriginal: $(@).data('level-original'), campaignID: $(@).data('campaign-id') } view.trigger 'level-moved', e if e.levelOriginal view.trigger 'adjacent-campaign-moved', e if e.campaignID @updateVolume() @@ -248,7 +247,7 @@ module.exports = class CampaignView extends RootView if level.requiresSubscription and @requiresSubscription and not @levelStatusMap[level.slug] and not level.adventurer @openModalView new SubscribeModal() window.tracker?.trackEvent 'Show subscription modal', category: 'Subscription', label: 'map level clicked', level: levelSlug - else if $(e.target).attr('disabled') + else if $(e.target).attr('disabled') and not me.isAdmin() Backbone.Mediator.publish 'router:navigate', route: '/contribute/adventurer' return else if $(e.target).parent().hasClass 'locked' From c54fd5ab4be6e6ee17587df4953fe2065ba1d49b Mon Sep 17 00:00:00 2001 From: Nick Winter Date: Mon, 29 Dec 2014 09:14:43 -0800 Subject: [PATCH 7/7] Moved editors from PUT to POST so that version saving behavior is preserved and admins can PUT without saving new versions. --- app/views/editor/ForkModal.coffee | 2 +- .../editor/article/ArticleEditView.coffee | 2 +- .../components/NewLevelComponentModal.coffee | 2 +- .../editor/level/modals/SaveLevelModal.coffee | 2 +- .../level/systems/NewLevelSystemModal.coffee | 2 +- app/views/editor/modal/NewModelModal.coffee | 2 +- .../editor/thang/ThangTypeEditView.coffee | 2 +- app/views/i18n/I18NEditModelView.coffee | 52 +++++++++---------- server/commons/Handler.coffee | 5 +- 9 files changed, 35 insertions(+), 36 deletions(-) diff --git a/app/views/editor/ForkModal.coffee b/app/views/editor/ForkModal.coffee index bc293c715..482f523b9 100644 --- a/app/views/editor/ForkModal.coffee +++ b/app/views/editor/ForkModal.coffee @@ -33,7 +33,7 @@ module.exports = class ForkModal extends ModalView if @model.schema().properties.permissions newModel.set 'permissions', [access: 'owner', target: me.id] newPathPrefix = "editor/#{@editorPath}/" - res = newModel.save() + res = newModel.save(null, {type: 'POST'}) # Override PUT so we can trigger postFirstVersion logic return unless res res.error => @hideLoading() diff --git a/app/views/editor/article/ArticleEditView.coffee b/app/views/editor/article/ArticleEditView.coffee index 583df2891..4cfaf04e8 100644 --- a/app/views/editor/article/ArticleEditView.coffee +++ b/app/views/editor/article/ArticleEditView.coffee @@ -83,7 +83,7 @@ module.exports = class ArticleEditView extends RootView newArticle = if e.major then @article.cloneNewMajorVersion() else @article.cloneNewMinorVersion() newArticle.set('commitMessage', e.commitMessage) - res = newArticle.save() + res = newArticle.save(null, {type: 'POST'}) # Override PUT so we can trigger postNewVersion logic return unless res modal = @$el.find('#save-version-modal') @enableModalInProgress(modal) diff --git a/app/views/editor/level/components/NewLevelComponentModal.coffee b/app/views/editor/level/components/NewLevelComponentModal.coffee index 141a45843..85251d743 100644 --- a/app/views/editor/level/components/NewLevelComponentModal.coffee +++ b/app/views/editor/level/components/NewLevelComponentModal.coffee @@ -28,7 +28,7 @@ module.exports = class NewLevelComponentModal extends ModalView component.set 'name', name component.set 'code', component.get('code', true).replace(/AttacksSelf/g, name) component.set 'permissions', [{access: 'owner', target: me.id}] # Private until saved in a published Level - res = component.save() + res = component.save(null, {type: 'POST'}) # Override PUT so we can trigger postFirstVersion logic return unless res @showLoading() diff --git a/app/views/editor/level/modals/SaveLevelModal.coffee b/app/views/editor/level/modals/SaveLevelModal.coffee index 1786ad44d..d18e402d7 100644 --- a/app/views/editor/level/modals/SaveLevelModal.coffee +++ b/app/views/editor/level/modals/SaveLevelModal.coffee @@ -97,7 +97,7 @@ module.exports = class SaveLevelModal extends SaveVersionModal tuples = _.zip(modelsToSave, formsToSave) for [newModel, form] in tuples newModel.updateI18NCoverage() if newModel.get('i18nCoverage') - res = newModel.save() + res = newModel.save(null, {type: 'POST'}) # Override PUT so we can trigger postNewVersion logic do (newModel, form) => res.error => @hideLoading() diff --git a/app/views/editor/level/systems/NewLevelSystemModal.coffee b/app/views/editor/level/systems/NewLevelSystemModal.coffee index 13e6cac38..193a50c5d 100644 --- a/app/views/editor/level/systems/NewLevelSystemModal.coffee +++ b/app/views/editor/level/systems/NewLevelSystemModal.coffee @@ -22,7 +22,7 @@ module.exports = class NewLevelSystemModal extends ModalView system.set 'name', name system.set 'code', system.get('code').replace(/Jitter/g, name) system.set 'permissions', [{access: 'owner', target: me.id}] # Private until saved in a published Level - res = system.save() + res = system.save(null, {type: 'POST'}) # Override PUT so we can trigger postFirstVersion logic return unless res @showLoading() diff --git a/app/views/editor/modal/NewModelModal.coffee b/app/views/editor/modal/NewModelModal.coffee index c336028a9..e0c98517b 100644 --- a/app/views/editor/modal/NewModelModal.coffee +++ b/app/views/editor/modal/NewModelModal.coffee @@ -36,7 +36,7 @@ module.exports = class NewModelModal extends ModalView onModelSubmitted: (e) -> e.preventDefault() model = @makeNewModel() - res = model.save() + res = model.save(null, {type: 'POST'}) # Override PUT so we can trigger postFirstVersion logic if needed return unless res forms.clearFormAlerts @$el diff --git a/app/views/editor/thang/ThangTypeEditView.coffee b/app/views/editor/thang/ThangTypeEditView.coffee index ba8616b7f..c5b62b576 100644 --- a/app/views/editor/thang/ThangTypeEditView.coffee +++ b/app/views/editor/thang/ThangTypeEditView.coffee @@ -367,7 +367,7 @@ module.exports = class ThangTypeEditView extends RootView newThangType.set('commitMessage', e.commitMessage) newThangType.updateI18NCoverage() if newThangType.get('i18nCoverage') - res = newThangType.save() + res = newThangType.save(null, {type: 'POST'}) # Override PUT so we can trigger postNewVersion logic return unless res modal = $('#save-version-modal') @enableModalInProgress(modal) diff --git a/app/views/i18n/I18NEditModelView.coffee b/app/views/i18n/I18NEditModelView.coffee index a3fa8d14b..38c620357 100644 --- a/app/views/i18n/I18NEditModelView.coffee +++ b/app/views/i18n/I18NEditModelView.coffee @@ -10,7 +10,7 @@ require 'views/modal/RevertModal' module.exports = class I18NEditModelView extends RootView className: 'editor i18n-edit-model-view' template: template - + events: 'change .translation-input': 'onInputChanged' 'change #language-select': 'onLanguageSelectChanged' @@ -22,11 +22,11 @@ module.exports = class I18NEditModelView extends RootView @model = @supermodel.loadModel(@model, 'model').model @model.saveBackups = true @selectedLanguage = me.get('preferredLanguage', true) - + showLoading: ($el) -> $el ?= @$el.find('.outer-content') super($el) - + onLoaded: -> super() @model.markToRevert() unless @model.hasLocalChanges() @@ -36,14 +36,14 @@ module.exports = class I18NEditModelView extends RootView c.model = @model c.selectedLanguage = @selectedLanguage - + @translationList = [] if @supermodel.finished() then @buildTranslationList() else [] result.index = index for result, index in @translationList c.translationList = @translationList - + c - + afterRender: -> super() @@ -63,7 +63,7 @@ module.exports = class I18NEditModelView extends RootView toEditor.on 'change', @onEditorChange editors = editors.concat([englishEditor, toEditor]) ) - + for editor in editors session = editor.getSession() session.setTabSize 2 @@ -80,17 +80,17 @@ module.exports = class I18NEditModelView extends RootView @onTranslationChanged(rowInfo, value) wrapRow: (title, key, enValue, toValue, path, format) -> - @translationList.push { + @translationList.push { title: title, - key: key, - enValue: enValue, - toValue: toValue or '', + key: key, + enValue: enValue, + toValue: toValue or '', path: path format: format } buildTranslationList: -> [] # overwrite - + onInputChanged: (e) -> index = $(e.target).data('index') rowInfo = @translationList[index] @@ -98,10 +98,10 @@ module.exports = class I18NEditModelView extends RootView @onTranslationChanged(rowInfo, value) onTranslationChanged: (rowInfo, value) -> - + #- Navigate down to where the translation will live base = @model.attributes - + for seg in rowInfo.path base = base[seg] @@ -109,19 +109,19 @@ module.exports = class I18NEditModelView extends RootView base[@selectedLanguage] ?= {} base = base[@selectedLanguage] - + if rowInfo.key.length > 1 for seg in rowInfo.key[..-2] base[seg] ?= {} base = base[seg] - + #- Set the data in a non-kosher way - + base[rowInfo.key[rowInfo.key.length-1]] = value @model.saveBackup() - + #- Enable patch submit button - + @$el.find('#patch-submit').attr('disabled', null) onLanguageSelectChanged: (e) -> @@ -131,19 +131,19 @@ module.exports = class I18NEditModelView extends RootView me.set('preferredLanguage', @selectedLanguage) me.patch() @render() - + onSubmitPatch: (e) -> - + delta = @model.getDelta() flattened = deltasLib.flattenDelta(delta) save = _.all(flattened, (delta) -> return _.isArray(delta.o) and delta.o.length is 1 and 'i18n' in delta.dataPath ) - + if save modelToSave = @model.cloneNewMinorVersion() modelToSave.updateI18NCoverage() if modelToSave.get('i18nCoverage') - + else modelToSave = new Patch() modelToSave.set 'delta', @model.getDelta() @@ -154,13 +154,13 @@ module.exports = class I18NEditModelView extends RootView if @modelClass.schema.properties.commitMessage commitMessage = "Diplomat submission for lang #{@selectedLanguage}: #{flattened.length} change(s)." - modelToSave.set 'commitMessage', commitMessage - + modelToSave.set 'commitMessage', commitMessage + errors = modelToSave.validate() button = $(e.target) button.attr('disabled', 'disabled') return button.text('Failed to Submit Changes') if errors - res = modelToSave.save() + res = modelToSave.save(null, {type: 'POST'}) # Override PUT so we can trigger postNewVersion logic return button.text('Failed to Submit Changes') unless res res.error => button.text('Error Submitting Changes') res.success => button.text('Submit Changes') diff --git a/server/commons/Handler.coffee b/server/commons/Handler.coffee index 8b21a2bd4..ecb6ba893 100644 --- a/server/commons/Handler.coffee +++ b/server/commons/Handler.coffee @@ -34,7 +34,7 @@ module.exports = class Handler hasAccessToDocument: (req, document, method=null) -> return true if req.user?.isAdmin() - if @modelClass.schema.uses_coco_translation_coverage and (method or req.method).toLowerCase() is 'put' + if @modelClass.schema.uses_coco_translation_coverage and (method or req.method).toLowerCase() is 'post' return true if @isJustFillingTranslations(req, document) if @modelClass.schema.uses_coco_permissions @@ -335,8 +335,7 @@ module.exports = class Handler put: (req, res, id) -> # Client expects PATCH behavior for PUTs # Real PATCHs return incorrect HTTP responses in some environments (e.g. Browserstack, schools) - return @postNewVersion(req, res) if @modelClass.schema.uses_coco_versions # Old logic - https://github.com/codecombat/codecombat/commit/0bdec68cfc2997a1d03458e516ecedd7c7f389a9#diff-859d2856438fffa609001ae3b7b74c27R331 - #return @sendForbiddenError(res) if @modelClass.schema.uses_coco_versions and not req.user.isAdmin() # New logic (from campaign editor) that breaks saving versioned documents, like in the level editor. + return @sendForbiddenError(res) if @modelClass.schema.uses_coco_versions and not req.user.isAdmin() # Campaign editor just saves over things. return @sendBadInputError(res, 'No input.') if _.isEmpty(req.body) return @sendForbiddenError(res) unless @hasAccess(req) @getDocumentForIdOrSlug req.body._id or id, (err, document) =>