mirror of
https://github.com/codeninjasllc/codecombat.git
synced 2024-11-28 01:55:38 -05:00
Merge branch 'master' of https://github.com/codecombat/codecombat
This commit is contained in:
commit
62ef17c776
27 changed files with 533 additions and 197 deletions
BIN
app/assets/images/pages/account/profile/sample_profile.png
Normal file
BIN
app/assets/images/pages/account/profile/sample_profile.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 376 KiB |
BIN
app/assets/images/pages/account/profile/sample_profile_thumb.png
Normal file
BIN
app/assets/images/pages/account/profile/sample_profile_thumb.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 88 KiB |
|
@ -39,6 +39,7 @@
|
|||
editor: "Editor"
|
||||
blog: "Blog"
|
||||
forum: "Forum"
|
||||
account: "Account"
|
||||
admin: "Admin"
|
||||
home: "Home"
|
||||
contribute: "Contribute"
|
||||
|
@ -173,6 +174,8 @@
|
|||
job_profile: "Job Profile"
|
||||
job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
|
||||
job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."
|
||||
sample_profile: "See a sample profile"
|
||||
view_profile: "View Your Profile"
|
||||
|
||||
account_profile:
|
||||
edit_settings: "Edit Settings"
|
||||
|
@ -309,6 +312,13 @@
|
|||
lg_title: "Latest Games"
|
||||
clas: "CLAs"
|
||||
|
||||
community:
|
||||
level_editor: "Level Editor"
|
||||
main_title: "CodeCombat Community"
|
||||
facebook: "Facebook"
|
||||
twitter: "Twitter"
|
||||
gplus: "Google+"
|
||||
|
||||
editor:
|
||||
main_title: "CodeCombat Editors"
|
||||
main_description: "Build your own levels, campaigns, units and educational content. We provide all the tools you need!"
|
||||
|
@ -318,8 +328,8 @@
|
|||
thang_description: "Build units, defining their default logic, graphics and audio. Currently only supports importing Flash exported vector graphics."
|
||||
level_title: "Level Editor"
|
||||
level_description: "Includes the tools for scripting, uploading audio, and constructing custom logic to create all sorts of levels. Everything we use ourselves!"
|
||||
security_notice: "Many major features in these editors are not currently enabled by default. As we improve the security of these systems, they will be made generally available. If you'd like to use these features sooner, "
|
||||
contact_us: "contact us!"
|
||||
got_questions: "Questions about using the CodeCombat editors?"
|
||||
contact_us: "Contact us!"
|
||||
hipchat_prefix: "You can also find us in our"
|
||||
hipchat_url: "HipChat room."
|
||||
back: "Back"
|
||||
|
|
|
@ -3,18 +3,18 @@ module.exports = nativeDescription: "日本語", englishDescription: "Japanese",
|
|||
loading: "ロード中"
|
||||
saving: "保存中..."
|
||||
sending: "送信中..."
|
||||
# send: "Send"
|
||||
send: "送信"
|
||||
cancel: "キャンセル"
|
||||
save: "保存"
|
||||
# publish: "Publish"
|
||||
# create: "Create"
|
||||
publish: "発行"
|
||||
create: "作成"
|
||||
delay_1_sec: "1秒"
|
||||
delay_3_sec: "3秒"
|
||||
delay_5_sec: "5秒"
|
||||
manual: "手動"
|
||||
# fork: "Fork"
|
||||
play: "ゲームスタート"
|
||||
# retry: "Retry"
|
||||
retry: "リトライ"
|
||||
|
||||
# units:
|
||||
# second: "second"
|
||||
|
@ -43,20 +43,20 @@ module.exports = nativeDescription: "日本語", englishDescription: "Japanese",
|
|||
about: "CoCoについて"
|
||||
contact: "お問い合わせ"
|
||||
twitter_follow: "フォロー"
|
||||
# employers: "Employers"
|
||||
employers: "雇用者の方へ"
|
||||
|
||||
versions:
|
||||
save_version_title: "新しいバージョンを保存"
|
||||
new_major_version: "メジャーバージョンを新しくする"
|
||||
cla_prefix: "変更を適用するには, 私達のCLAに同意する必要があります。"
|
||||
# cla_url: "CLA"
|
||||
cla_url: "CLA"
|
||||
# cla_suffix: "."
|
||||
cla_agree: "同意する"
|
||||
|
||||
login:
|
||||
sign_up: "アカウント登録"
|
||||
log_in: "ログイン"
|
||||
# logging_in: "Logging In"
|
||||
logging_in: "ログイン中"
|
||||
log_out: "ログアウト"
|
||||
recover: "パスワードを忘れた場合はこちら"
|
||||
|
||||
|
@ -68,24 +68,24 @@ module.exports = nativeDescription: "日本語", englishDescription: "Japanese",
|
|||
create_account_title: "進行状況保存用のアカウント作成"
|
||||
description: "無料でご登録いただけます。"
|
||||
email_announcements: "メールでお知らせを受け取る"
|
||||
coppa: "13歳以上または米国以外"
|
||||
coppa: "13歳以上または米国以外"
|
||||
coppa_why: "(COPPAって?)"
|
||||
creating: "アカウントを作成しています..."
|
||||
sign_up: "アカウント登録"
|
||||
log_in: "パスワードでログイン"
|
||||
# social_signup: "Or, you can sign up through Facebook or G+:"
|
||||
social_signup: "あるいはFacebookやGoogle+でログイン:"
|
||||
|
||||
home:
|
||||
slogan: "ゲームをプレイしてJavaScriptを学びましょう"
|
||||
no_ie: "大変申し訳ありませんが、ご利用のブラウザ(IE8以下)はサポートされていません。(ChromeやFirefoxをご利用ください)"
|
||||
no_mobile: "CodeCombat は携帯端末向けに制作されていないため、動作しない可能性があります。"
|
||||
play: "ゲームスタート"
|
||||
# old_browser: "Uh oh, your browser is too old to run CodeCombat. Sorry!"
|
||||
# old_browser_suffix: "You can try anyway, but it probably won't work."
|
||||
# campaign: "Campaign"
|
||||
# for_beginners: "For Beginners"
|
||||
# multiplayer: "Multiplayer"
|
||||
# for_developers: "For Developers"
|
||||
old_browser: "ご利用のブラウザはCodeCombatを動作させるには古すぎるようです"
|
||||
old_browser_suffix: "このまま進めることもできますが、正常動作は保証されません"
|
||||
campaign: "キャンペーンモード"
|
||||
for_beginners: "初心者向け"
|
||||
multiplayer: "マルチプレイヤー"
|
||||
for_developers: "開発者向け"
|
||||
|
||||
play:
|
||||
choose_your_level: "レベル選択"
|
||||
|
@ -150,14 +150,14 @@ module.exports = nativeDescription: "日本語", englishDescription: "Japanese",
|
|||
wizard_tab: "魔法使い"
|
||||
password_tab: "パスワード"
|
||||
emails_tab: "メール"
|
||||
# admin: "Admin"
|
||||
admin: "管理者"
|
||||
wizard_color: "ウィザードの色"
|
||||
new_password: "新パスワード"
|
||||
new_password_verify: "新パスワードを再入力"
|
||||
email_subscriptions: "ニュースレターの購読"
|
||||
email_announcements: "お知らせ"
|
||||
# email_notifications: "Notifications"
|
||||
# email_notifications_description: "Get periodic notifications for your account."
|
||||
email_notifications: "通知"
|
||||
email_notifications_description: "定期的なお知らせをメールで受け取る"
|
||||
email_announcements_description: "CodeCombatの最新のニュースや進展をメールで受け取る"
|
||||
contributor_emails: "開発を手伝ってくれる人向けのメール"
|
||||
contribute_prefix: "私達は開発を手伝ってくれる人を探しています。 詳しくは "
|
||||
|
@ -177,27 +177,27 @@ module.exports = nativeDescription: "日本語", englishDescription: "Japanese",
|
|||
profile_for_suffix: "のプロフィール"
|
||||
# approved: "Approved"
|
||||
# not_approved: "Not Approved"
|
||||
# looking_for: "Looking for:"
|
||||
# last_updated: "Last updated:"
|
||||
looking_for: "検索:"
|
||||
last_updated: "最終更新:"
|
||||
# contact: "Contact"
|
||||
# work_experience: "Work Experience"
|
||||
# education: "Education"
|
||||
# our_notes: "Our Notes"
|
||||
# projects: "Projects"
|
||||
|
||||
# employers:
|
||||
# want_to_hire_our_players: "Want to hire expert CodeCombat players?"
|
||||
# contact_george: "Contact George to see our candidates"
|
||||
# candidates_count_prefix: "We currently have "
|
||||
# candidates_count_many: "many"
|
||||
# candidates_count_suffix: "highly skilled and vetted developers looking for work."
|
||||
# candidate_name: "Name"
|
||||
# candidate_location: "Location"
|
||||
# candidate_looking_for: "Looking For"
|
||||
# candidate_role: "Role"
|
||||
# candidate_top_skills: "Top Skills"
|
||||
# candidate_years_experience: "Yrs Exp"
|
||||
# candidate_last_updated: "Last Updated"
|
||||
employers:
|
||||
want_to_hire_our_players: "CodeCombatのエキスパートプレイヤーをお探しですか?"
|
||||
contact_george: "候補者に会うためにGeorgeに連絡してください"
|
||||
candidates_count_prefix: "現在、仕事を探している優秀で審査済みの開発者が"
|
||||
candidates_count_many: "多数"
|
||||
candidates_count_suffix: "います"
|
||||
candidate_name: "名前"
|
||||
candidate_location: "勤務地"
|
||||
candidate_looking_for: "希望"
|
||||
candidate_role: "職種"
|
||||
candidate_top_skills: "得意分野"
|
||||
candidate_years_experience: "経験年数"
|
||||
candidate_last_updated: "最終更新日時"
|
||||
|
||||
play_level:
|
||||
level_load_error: "レベルがロード出来ませんでした: "
|
||||
|
@ -219,13 +219,13 @@ module.exports = nativeDescription: "日本語", englishDescription: "Japanese",
|
|||
victory_sign_up: "進行状況を保存するにはアカウント登録をしてください"
|
||||
victory_sign_up_poke: "あなたのコードを保存してみませんか? 無料アカウント登録!"
|
||||
victory_rate_the_level: "このレベルの評価: "
|
||||
# victory_rank_my_game: "Rank My Game"
|
||||
# victory_ranking_game: "Submitting..."
|
||||
victory_rank_my_game: "ゲームを記録を送信する"
|
||||
victory_ranking_game: "送信中..."
|
||||
# victory_return_to_ladder: "Return to Ladder"
|
||||
victory_play_next_level: "次のレベル"
|
||||
victory_go_home: "ホームに戻る"
|
||||
victory_review: "フィードバック"
|
||||
# victory_hour_of_code_done: "Are You Done?"
|
||||
victory_hour_of_code_done: "完了してよろしいですか?"
|
||||
# victory_hour_of_code_done_yes: "Yes, I'm finished with my Hour of Code™!"
|
||||
multiplayer_title: "マルチプレイ設定"
|
||||
multiplayer_link_description: "このURLを一緒にプレイしたい人に教えてください。"
|
||||
|
@ -298,17 +298,17 @@ module.exports = nativeDescription: "日本語", englishDescription: "Japanese",
|
|||
admin:
|
||||
av_title: "管理画面"
|
||||
# av_entities_sub_title: "Entities"
|
||||
# av_entities_users_url: "Users"
|
||||
av_entities_users_url: "ユーザー"
|
||||
# av_entities_active_instances_url: "Active Instances"
|
||||
# av_other_sub_title: "Other"
|
||||
av_other_sub_title: "その他"
|
||||
# av_other_debug_base_url: "Base (for debugging base.jade)"
|
||||
# u_title: "User List"
|
||||
# lg_title: "Latest Games"
|
||||
# clas: "CLAs"
|
||||
lg_title: "最近のゲーム"
|
||||
clas: "CLA"
|
||||
|
||||
# editor:
|
||||
# main_title: "CodeCombat Editors"
|
||||
# main_description: "Build your own levels, campaigns, units and educational content. We provide all the tools you need!"
|
||||
editor:
|
||||
main_title: "CodeCombatエディター"
|
||||
main_description: "新しいレベル、キャンペーン、ユニットそして教育コンテンツを構築しましょう。"
|
||||
# article_title: "Article Editor"
|
||||
# article_description: "Write articles that give players overviews of programming concepts which can be used across a variety of levels and campaigns."
|
||||
# thang_title: "Thang Editor"
|
||||
|
|
|
@ -6,7 +6,7 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
|
|||
send: "Отправить"
|
||||
cancel: "Отмена"
|
||||
save: "Сохранить"
|
||||
# publish: "Publish"
|
||||
publish: "Опубликовать"
|
||||
create: "Создать"
|
||||
delay_1_sec: "1 секунда"
|
||||
delay_3_sec: "3 секунды"
|
||||
|
@ -73,7 +73,7 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
|
|||
creating: "Создание аккаунта..."
|
||||
sign_up: "Регистрация"
|
||||
log_in: "вход с паролем"
|
||||
# social_signup: "Or, you can sign up through Facebook or G+:"
|
||||
social_signup: "Или вы можете зарегестрироваться через Facebook или G+:"
|
||||
|
||||
home:
|
||||
slogan: "Научитесь программировать на JavaScript, играя в игру"
|
||||
|
@ -291,9 +291,9 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
|
|||
time_current: "Текущее:"
|
||||
time_total: "Максимальное:"
|
||||
time_goto: "Перейти на:"
|
||||
# infinite_loop_try_again: "Try Again"
|
||||
# infinite_loop_reset_level: "Reset Level"
|
||||
# infinite_loop_comment_out: "Comment Out My Code"
|
||||
infinite_loop_try_again: "Попробовать снова"
|
||||
infinite_loop_reset_level: "Сбросить уровень"
|
||||
infinite_loop_comment_out: "Закомментировать мой код"
|
||||
|
||||
admin:
|
||||
av_title: "Админ панель"
|
||||
|
@ -361,7 +361,7 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
|
|||
thang_search_title: "Искать типы объектов"
|
||||
level_search_title: "Искать уровни"
|
||||
signup_to_create: "Авторизуйтесь для создания нового контента"
|
||||
# read_only_warning2: "Note: you can't save any edits here, because you're not logged in."
|
||||
read_only_warning2: "Примечание: вы не можете сохранять любые правки здесь, потому что вы не авторизованы."
|
||||
|
||||
article:
|
||||
edit_btn_preview: "Предпросмотр"
|
||||
|
@ -395,7 +395,7 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
|
|||
easy: "Просто"
|
||||
medium: "Нормально"
|
||||
hard: "Сложно"
|
||||
# player: "Player"
|
||||
player: "Игрок"
|
||||
|
||||
about:
|
||||
who_is_codecombat: "Кто стоит за CodeCombat?"
|
||||
|
@ -600,9 +600,9 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
|
|||
simulate_all: "СБРОСИТЬ И СИМУЛИРОВАТЬ ИГРЫ"
|
||||
games_simulated_by: "Игры, симулированные вами:"
|
||||
games_simulated_for: "Игры, симулированные за вас:"
|
||||
# games_simulated: "Games simulated"
|
||||
# games_played: "Games played"
|
||||
# ratio: "Ratio"
|
||||
games_simulated: "Игр симулировано"
|
||||
games_played: "Игр сыграно"
|
||||
ratio: "Соотношение"
|
||||
leaderboard: "таблица лидеров"
|
||||
battle_as: "Сразиться за "
|
||||
summary_your: "Ваши "
|
||||
|
@ -667,5 +667,5 @@ module.exports = nativeDescription: "русский", englishDescription: "Russi
|
|||
leaderboard: "таблица лидеров"
|
||||
user_schema: "Пользовательская Schema"
|
||||
user_profile: "Пользовательский профиль"
|
||||
# patches: "Patches"
|
||||
# model: "Model"
|
||||
patches: "Патчи"
|
||||
model: "Модель"
|
||||
|
|
|
@ -6,7 +6,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
|
|||
send: "发送"
|
||||
cancel: "取消"
|
||||
save: "保存"
|
||||
# publish: "Publish"
|
||||
publish: "发布"
|
||||
create: "创建"
|
||||
delay_1_sec: "1 秒"
|
||||
delay_3_sec: "3 秒"
|
||||
|
@ -73,7 +73,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
|
|||
creating: "账户创建中……"
|
||||
sign_up: "注册"
|
||||
log_in: "登录"
|
||||
# social_signup: "Or, you can sign up through Facebook or G+:"
|
||||
social_signup: "或者,你可以通过Facebook或G+注册:"
|
||||
|
||||
home:
|
||||
slogan: "通过游戏学习 Javascript"
|
||||
|
@ -114,7 +114,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
|
|||
forum_page: "我们的论坛"
|
||||
forum_suffix: ""
|
||||
send: "反馈意见"
|
||||
# contact_candidate: "Contact Candidate"
|
||||
contact_candidate: "联系参选人"
|
||||
# recruitment_reminder: "Use this form to reach out to candidates you are interested in interviewing. Remember that CodeCombat charges 18% of first-year salary. The fee is due upon hiring the employee and is refundable for 90 days if the employee does not remain employed. Part time, remote, and contract employees are free, as are interns."
|
||||
|
||||
diplomat_suggestion:
|
||||
|
@ -128,13 +128,13 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
|
|||
wizard_settings:
|
||||
title: "设置向导"
|
||||
customize_avatar: "设置你的头像"
|
||||
# active: "Active"
|
||||
# color: "Color"
|
||||
# group: "Group"
|
||||
active: "启用"
|
||||
color: "颜色"
|
||||
group: "类别"
|
||||
clothes: "衣服"
|
||||
trim: "条纹"
|
||||
cloud: "云"
|
||||
# team: "Team"
|
||||
team: "队伍"
|
||||
spell: "魔法球"
|
||||
boots: "鞋子"
|
||||
hue: "颜色"
|
||||
|
@ -167,37 +167,37 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
|
|||
error_saving: "保存时出错"
|
||||
saved: "更改已保存"
|
||||
password_mismatch: "密码不匹配。"
|
||||
# job_profile: "Job Profile"
|
||||
# job_profile_approved: "Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks."
|
||||
# job_profile_explanation: "Hi! Fill this out, and we will get in touch about finding you a software developer job."
|
||||
job_profile: "工作经历"
|
||||
job_profile_approved: "你填写的工作经历将由CodeCombat认证. 雇主将看到这些信息,除非你将它设置为不启用状态或者连续四周没有更新."
|
||||
job_profile_explanation: "你好! 填写这些信息, 我们将使用它帮你寻找一份软件开发的工作."
|
||||
|
||||
account_profile:
|
||||
edit_settings: "编辑设置"
|
||||
profile_for_prefix: "关于他的基本资料:"
|
||||
profile_for_suffix: ""
|
||||
# approved: "Approved"
|
||||
# not_approved: "Not Approved"
|
||||
# looking_for: "Looking for:"
|
||||
# last_updated: "Last updated:"
|
||||
# contact: "Contact"
|
||||
# work_experience: "Work Experience"
|
||||
# education: "Education"
|
||||
approved: "已认证"
|
||||
not_approved: "为认证"
|
||||
looking_for: "寻找"
|
||||
last_updated: "最后一次更新:"
|
||||
contact: "联系"
|
||||
work_experience: "工作经验"
|
||||
education: "教育程度"
|
||||
# our_notes: "Our Notes"
|
||||
# projects: "Projects"
|
||||
projects: "项目"
|
||||
|
||||
# employers:
|
||||
# want_to_hire_our_players: "Want to hire expert CodeCombat players?"
|
||||
# contact_george: "Contact George to see our candidates"
|
||||
# candidates_count_prefix: "We currently have "
|
||||
# candidates_count_many: "many"
|
||||
# candidates_count_suffix: "highly skilled and vetted developers looking for work."
|
||||
# candidate_name: "Name"
|
||||
# candidate_location: "Location"
|
||||
# candidate_looking_for: "Looking For"
|
||||
# candidate_role: "Role"
|
||||
# candidate_top_skills: "Top Skills"
|
||||
# candidate_years_experience: "Yrs Exp"
|
||||
# candidate_last_updated: "Last Updated"
|
||||
want_to_hire_our_players: "想要雇用CodeCombat上的专业玩家?"
|
||||
contact_george: "联系George查看”为我们义务工作的人"
|
||||
candidates_count_prefix: "我们当前有 "
|
||||
candidates_count_many: "很多"
|
||||
candidates_count_suffix: "经过我们认证的高手们正在找工作。"
|
||||
candidate_name: "姓名"
|
||||
candidate_location: "地点"
|
||||
candidate_looking_for: "寻找"
|
||||
candidate_role: "角色"
|
||||
candidate_top_skills: "高级技能"
|
||||
candidate_years_experience: "多年工作经验"
|
||||
candidate_last_updated: "最后一次更新"
|
||||
|
||||
play_level:
|
||||
level_load_error: "关卡不能载入: "
|
||||
|
@ -250,17 +250,17 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
|
|||
editor_config_title: "编辑器配置"
|
||||
editor_config_language_label: "编程语言"
|
||||
editor_config_language_description: "请输入你想写的编程语言."
|
||||
# editor_config_keybindings_label: "Key Bindings"
|
||||
# editor_config_keybindings_default: "Default (Ace)"
|
||||
editor_config_keybindings_label: "按键设置s"
|
||||
editor_config_keybindings_default: "默认 (Ace)"
|
||||
# editor_config_keybindings_description: "Adds additional shortcuts known from the common editors."
|
||||
# editor_config_invisibles_label: "Show Invisibles"
|
||||
# editor_config_invisibles_description: "Displays invisibles such as spaces or tabs."
|
||||
# editor_config_indentguides_label: "Show Indent Guides"
|
||||
# editor_config_indentguides_description: "Displays vertical lines to see indentation better."
|
||||
editor_config_invisibles_label: "显示隐藏的"
|
||||
editor_config_invisibles_description: "显示诸如空格或TAB键。"
|
||||
editor_config_indentguides_label: "显示缩进提示"
|
||||
editor_config_indentguides_description: "显示一条竖线以使缩进更明显。"
|
||||
# editor_config_behaviors_label: "Smart Behaviors"
|
||||
# editor_config_behaviors_description: "Autocompletes brackets, braces, and quotes."
|
||||
editor_config_behaviors_description: "自动完成括号,大括号和引号。"
|
||||
loading_ready: "载入完成!"
|
||||
# tip_insert_positions: "Shift+Click a point on the map to insert it into the spell editor."
|
||||
tip_insert_positions: "使用Shift+左键来插入拼写编辑器。"
|
||||
tip_toggle_play: "用 Ctrl+P 来暂停或继续"
|
||||
tip_scrub_shortcut: "用 Ctrl+[ 和 Ctrl+] 来倒退和快进."
|
||||
tip_guide_exists: "点击页面上方的指南, 可以获得更多有用信息."
|
||||
|
@ -269,31 +269,31 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
|
|||
tip_js_beginning: "JavaScript 仅仅只是个开始."
|
||||
# tip_autocast_setting: "Adjust autocast settings by clicking the gear on the cast button."
|
||||
think_solution: "思考解决方法, 而不是问题."
|
||||
# tip_theory_practice: "In theory, there is no difference between theory and practice. But in practice, there is. - Yogi Berra"
|
||||
# tip_error_free: "There are two ways to write error-free programs; only the third one works. - Alan Perlis"
|
||||
# tip_debugging_program: "If debugging is the process of removing bugs, then programming must be the process of putting them in. - Edsger W. Dijkstra"
|
||||
# tip_forums: "Head over to the forums and tell us what you think!"
|
||||
# tip_baby_coders: "In the future, even babies will be Archmages."
|
||||
tip_theory_practice: "在理论研究中,理论和实践之间是没有区别的。但在实践中,它们是有区别的。 - Yogi Berra"
|
||||
tip_error_free: "有两种方式可以写出没有错误的程序;但是只有第三种方式能让程序达到预期的效果。 - Alan Perlis"
|
||||
tip_debugging_program: "如果说调试是清除Bug的过程,那么编码就是放置Bug的过程。- Edsger W. Dijkstra"
|
||||
tip_forums: "到论坛去告诉我们你的想法!"
|
||||
tip_baby_coders: "在未来,就算小孩都能成为大法师."
|
||||
# tip_morale_improves: "Loading will continue until morale improves."
|
||||
# tip_all_species: "We believe in equal opportunities to learn programming for all species."
|
||||
tip_all_species: "我们相信学习编程的机会对任何种族都是平等的。"
|
||||
# tip_reticulating: "Reticulating spines."
|
||||
tip_harry: "巫师, "
|
||||
# tip_great_responsibility: "With great coding skill comes great debug responsibility."
|
||||
# tip_munchkin: "If you don't eat your vegetables, a munchkin will come after you while you're asleep."
|
||||
tip_great_responsibility: "更高的编程技巧也意味着更大的调试责任。"
|
||||
tip_munchkin: "如果你不吃掉你的蔬菜, 一个小矮人将在你睡着之后来找你。"
|
||||
tip_binary: "这个世界上只有 10 种人: 那些懂二进制的, 还有那些不懂二进制的."
|
||||
# tip_commitment_yoda: "A programmer must have the deepest commitment, the most serious mind. ~ Yoda"
|
||||
tip_commitment_yoda: "一个程序员必须有高度的责任感和一颗认真的心。 ~ 尤达大师"
|
||||
tip_no_try: "做. 或是不做. 这世上不存在'尝试'这种东西. - 尤达大师"
|
||||
# tip_patience: "Patience you must have, young Padawan. - Yoda"
|
||||
tip_patience: "你必须要有耐心,年轻的学徒 - 尤达大师"
|
||||
tip_documented_bug: "一个写在文档里的漏洞不算漏洞, 那是个功能."
|
||||
tip_impossible: "It always seems impossible until it's done. - Nelson Mandela"
|
||||
tip_impossible: "在事情未完成之前,一切都看似不可能. - 纳尔逊·曼德拉"
|
||||
tip_talk_is_cheap: "多说无用, 亮出你的代码. - Linus Torvalds"
|
||||
# tip_first_language: "The most disastrous thing that you can ever learn is your first programming language. - Alan Kay"
|
||||
tip_first_language: "你所经历过最可怕的事情是你的第一门编程语言。 - Alan Kay"
|
||||
time_current: "现在:"
|
||||
time_total: "最大:"
|
||||
time_goto: "跳到:"
|
||||
# infinite_loop_try_again: "Try Again"
|
||||
# infinite_loop_reset_level: "Reset Level"
|
||||
# infinite_loop_comment_out: "Comment Out My Code"
|
||||
infinite_loop_try_again: "请重试"
|
||||
infinite_loop_reset_level: "重置等级"
|
||||
infinite_loop_comment_out: "为我的代码添加注释"
|
||||
|
||||
admin:
|
||||
av_title: "管理员视图"
|
||||
|
@ -361,7 +361,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
|
|||
thang_search_title: "在这里搜索物品类型"
|
||||
level_search_title: "在这里搜索关卡"
|
||||
signup_to_create: "注册之后就可以创建一个新的关卡"
|
||||
# read_only_warning2: "Note: you can't save any edits here, because you're not logged in."
|
||||
read_only_warning2: "提示:你不能保存任何编辑,因为你没有登陆"
|
||||
|
||||
article:
|
||||
edit_btn_preview: "预览"
|
||||
|
@ -373,13 +373,13 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
|
|||
body: "正文"
|
||||
version: "版本"
|
||||
commit_msg: "提交信息"
|
||||
# version_history: "Version History"
|
||||
version_history: "版本历史"
|
||||
version_history_for: "版本历史: "
|
||||
result: "结果"
|
||||
results: "结果"
|
||||
description: "描述"
|
||||
or: "或"
|
||||
# subject: "Subject"
|
||||
subject: "主题"
|
||||
email: "邮件"
|
||||
password: "密码"
|
||||
message: "信息"
|
||||
|
@ -395,7 +395,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
|
|||
easy: "容易"
|
||||
medium: "中等"
|
||||
hard: "困难"
|
||||
# player: "Player"
|
||||
player: "玩家"
|
||||
|
||||
about:
|
||||
who_is_codecombat: "什么是 CodeCombat?"
|
||||
|
@ -538,7 +538,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
|
|||
scribe_introduction_url_mozilla: "Mozilla 开发者社区"
|
||||
# scribe_introduction_suf: " has built. If your idea of fun is articulating the concepts of programming in Markdown form, then this class might be for you."
|
||||
# scribe_attribute_1: "Skill in words is pretty much all you need. Not only grammar and spelling, but able to convey complicated ideas to others."
|
||||
# contact_us_url: "Contact us"
|
||||
contact_us_url: "联系我们"
|
||||
scribe_join_description: "介绍一下你自己, 比如你的编程经历和你喜欢写什么东西, 我们将从这里开始了解你!!"
|
||||
more_about_scribe: "了解如何成为一名文书"
|
||||
scribe_subscribe_desc: "通过电子邮件获得写作新文档的通知。"
|
||||
|
@ -610,7 +610,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
|
|||
summary_wins: " 胜利, "
|
||||
summary_losses: " 失败"
|
||||
rank_no_code: "没有新代码可供评分"
|
||||
# rank_my_game: "Rank My Game!"
|
||||
rank_my_game: "为我的游戏评分!"
|
||||
rank_submitting: "正在提交..."
|
||||
# rank_submitted: "Submitted for Ranking"
|
||||
rank_failed: "评分失败"
|
||||
|
@ -665,7 +665,7 @@ module.exports = nativeDescription: "简体中文", englishDescription: "Chinese
|
|||
gplus_friends: "G+ 朋友"
|
||||
# gplus_friend_sessions: "G+ Friend Sessions"
|
||||
leaderboard: "排行榜"
|
||||
# user_schema: "User Schema"
|
||||
# user_profile: "User Profile"
|
||||
# patches: "Patches"
|
||||
user_schema: "用户模式"
|
||||
user_profile: "User Profile"
|
||||
patches: "补丁"
|
||||
# model: "Model"
|
||||
|
|
|
@ -58,7 +58,7 @@ UserSchema = c.object {},
|
|||
jobProfile: c.object {title: 'Job Profile', required: ['lookingFor', 'jobTitle', 'active', 'name', 'city', 'country', 'skills', 'experience', 'shortDescription', 'longDescription', 'visa', 'work', 'education', 'projects', 'links']},
|
||||
lookingFor: {title: 'Looking For', type: 'string', enum: ['Full-time', 'Part-time', 'Remote', 'Contracting', 'Internship'], default: 'Full-time', description: 'What kind of developer position do you want?'}
|
||||
jobTitle: {type: 'string', maxLength: 50, title: 'Desired Job Title', description: 'What role are you looking for? Ex.: "Full Stack Engineer", "Front-End Developer", "iOS Developer"', default: 'Software Developer'}
|
||||
active: {title: 'Active', type: 'boolean', description: 'Want interview offers right now?'}
|
||||
active: {title: 'Open to Offers', type: 'boolean', description: 'Want interview offers right now?'}
|
||||
updated: c.date {title: 'Last Updated', description: 'How fresh your profile appears to employers. Profiles go inactive after 4 weeks.'}
|
||||
name: c.shortString {title: 'Name', description: 'Name you want employers to see, like "Nick Winter".'}
|
||||
city: c.shortString {title: 'City', description: 'City you want to work in (or live in now), like "San Francisco" or "Lubbock, TX".', default: 'Defaultsville, CA', format: 'city'}
|
||||
|
@ -74,13 +74,14 @@ UserSchema = c.object {},
|
|||
employer: c.shortString {title: 'Employer', description: 'Name of your employer.'}
|
||||
role: c.shortString {title: 'Job Title', description: 'What was your job title or role?'}
|
||||
duration: c.shortString {title: 'Duration', description: 'When did you hold this gig? Ex.: "Feb 2013 - present".'}
|
||||
description: {type: 'string', title: 'Description', description: 'What did you do there? (140 chars)', maxLength: 140}
|
||||
description: {type: 'string', title: 'Description', description: 'What did you do there? (140 chars; optional)', maxLength: 140}
|
||||
education: c.array {title: 'Education', description: 'List your academic ordeals.'},
|
||||
c.object {title: 'Ordeal', description: 'Some education that befell you.', required: ['school', 'degree', 'duration']},
|
||||
school: c.shortString {title: 'School', description: 'Name of your school.'}
|
||||
degree: c.shortString {title: 'Degree', description: 'What was your degree and field of study? Ex. Ph.D. Human-Computer Interaction (incomplete)'}
|
||||
duration: c.shortString {title: 'Dates', description: 'When? Ex.: "Aug 2004 - May 2008".'}
|
||||
projects: c.array {title: 'Projects', description: 'Highlight your projects to amaze employers.', maxItems: 3},
|
||||
description: {type: 'string', title: 'Description', description: 'Highlight anything about this educational experience. (140 chars; optional)', maxLength: 140}
|
||||
projects: c.array {title: 'Projects (Top 3)', description: 'Highlight your projects to amaze employers.', maxItems: 3},
|
||||
c.object {title: 'Project', description: 'A project you created.', required: ['name', 'description', 'picture'], default: {name: 'My Project', description: 'A project I worked on.', link: 'http://example.com', picture: ''}},
|
||||
name: c.shortString {title: 'Project Name', description: 'What was the project called?', default: 'My Project'}
|
||||
description: {type: 'string', title: 'Description', description: 'Briefly describe the project.', maxLength: 400, default: 'A project I worked on.', format: 'markdown'}
|
||||
|
@ -94,6 +95,8 @@ UserSchema = c.object {},
|
|||
|
||||
jobProfileApproved: {title: 'Job Profile Approved', type: 'boolean', description: 'Whether your profile has been approved by CodeCombat.'}
|
||||
jobProfileNotes: {type: 'string', maxLength: 1000, title: 'Our Notes', description: "CodeCombat's notes on the candidate.", format: 'markdown', default: ''}
|
||||
employerAt: c.shortString {description: "If given employer permissions to view job candidates, for which employer?"}
|
||||
|
||||
c.extendBasicProperties UserSchema, 'user'
|
||||
|
||||
module.exports = UserSchema
|
||||
|
|
|
@ -44,6 +44,26 @@
|
|||
.form
|
||||
max-width: 600px
|
||||
|
||||
#job-profile-view
|
||||
.profile-preview-button
|
||||
&.bottom-preview
|
||||
margin: 15px 0 0 0
|
||||
|
||||
.sample-profile-thumbnail
|
||||
margin-top: -60px
|
||||
|
||||
.profile-completion-progress
|
||||
width: 100%
|
||||
display: inline-block
|
||||
height: 33px
|
||||
|
||||
.progress-bar
|
||||
line-height: 33px
|
||||
|
||||
.progress-next-item
|
||||
margin-top: -20px
|
||||
margin-bottom: 15px
|
||||
|
||||
#job-profile-treema
|
||||
background-color: white
|
||||
|
||||
|
@ -54,3 +74,16 @@
|
|||
font-size: 14px
|
||||
line-height: 22px
|
||||
opacity: 1
|
||||
|
||||
.treema-row
|
||||
padding-top: 6px
|
||||
|
||||
.treema-image-file
|
||||
.btn:after
|
||||
content: "Upload Picture"
|
||||
margin-left: 20px
|
||||
|
||||
img
|
||||
display: block
|
||||
clear: both
|
||||
max-width: 300px
|
||||
|
|
|
@ -10,16 +10,19 @@
|
|||
font-weight: 400
|
||||
letter-spacing: 1px
|
||||
|
||||
.navbuttontext-user-name
|
||||
max-width: 110px
|
||||
overflow: hidden
|
||||
text-overflow: ellipsis
|
||||
white-space: nowrap
|
||||
.navbuttontext-account
|
||||
display: inline-block
|
||||
padding: 0 5px 0 0
|
||||
margin: 0
|
||||
margin: 0 5px 0 0
|
||||
height: 18px
|
||||
|
||||
.account-settings-image
|
||||
width: 18px
|
||||
height: 18px
|
||||
|
||||
.glyphicon-user
|
||||
font-size: 16px
|
||||
|
||||
.nav.navbar-link-text, .nav.navbar-link-text > li > a
|
||||
font-weight: normal
|
||||
font-size: 25px
|
||||
|
|
7
app/styles/community.sass
Normal file
7
app/styles/community.sass
Normal file
|
@ -0,0 +1,7 @@
|
|||
#community-view
|
||||
|
||||
.community_columns
|
||||
width: 330px
|
||||
float: left
|
||||
padding-left: 10px
|
||||
padding-right: 10px
|
|
@ -26,7 +26,8 @@
|
|||
.navbar
|
||||
min-height: 0px
|
||||
border-radius: 0
|
||||
.navbar-right // not sure why bootstrap puts a big negative margin in, but this overrides it
|
||||
.navbar-right
|
||||
// not sure why bootstrap puts a big negative margin in, but this overrides it
|
||||
margin-right: 10px
|
||||
|
||||
// custom navbar styling
|
||||
|
@ -84,4 +85,4 @@
|
|||
|
||||
.treema-root
|
||||
background-color: white
|
||||
border-radius: 4px
|
||||
border-radius: 4px
|
||||
|
|
|
@ -1,8 +1,28 @@
|
|||
h3(data-i18n="account_settings.job_profile") Job Profile
|
||||
|
||||
if me.get('jobProfileApproved')
|
||||
p.lead(data-i18n="account_settings.job_profile_approved") Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks.
|
||||
else
|
||||
p.lead(data-i18n="account_settings.job_profile_explanation") Hi! Fill this out, and we will get in touch about finding you a software developer job.
|
||||
.row
|
||||
.col-md-9
|
||||
if me.get('jobProfileApproved')
|
||||
p.lead(data-i18n="account_settings.job_profile_approved") Your job profile has been approved by CodeCombat. Employers will be able to see it until you either mark it inactive or it has not been changed for four weeks.
|
||||
else
|
||||
p.lead(data-i18n="account_settings.job_profile_explanation") Hi! Fill this out, and we will get in touch about finding you a software developer job.
|
||||
|
||||
#job-profile-treema
|
||||
.row
|
||||
.col-md-9
|
||||
.progress.profile-completion-progress
|
||||
.progress-bar.progress-bar-success
|
||||
.progress-next-item
|
||||
|
||||
.col-md-3
|
||||
a.btn.btn-large.btn-primary.profile-preview-button.top-preview(href="/account/profile/#{me.id}", target="job_profile", data-i18n="account_settings.view_profile") View Your Profile
|
||||
|
||||
.col-md-3
|
||||
.thumbnail.sample-profile-thumbnail
|
||||
a(href="http://codecombat.com/images/pages/account/profile/sample_profile.png", target="_blank")
|
||||
img(src="/images/pages/account/profile/sample_profile_thumb.png" alt="Sample Profile Thumbnail")
|
||||
.caption
|
||||
span(data-i18n="account_settings.sample_profile") See a sample profile
|
||||
|
||||
#job-profile-treema
|
||||
|
||||
a.btn.btn-large.btn-primary.profile-preview-button.bottom-preview(href="/account/profile/#{me.id}", target="job_profile", data-i18n="account_settings.view_profile") View Your Profile
|
||||
|
|
|
@ -5,7 +5,7 @@ block content
|
|||
if myProfile || (me.isAdmin() && user.get('jobProfile'))
|
||||
.profile-control-bar
|
||||
if myProfile
|
||||
a(href="/account/settings")
|
||||
a(href=user.get('jobProfile') ? "/account/settings#job-profile" : "/account/settings")
|
||||
button.btn.edit-settings-button
|
||||
i.icon-cog
|
||||
span(data-i18n="account_profile.edit_settings") Edit Settings
|
||||
|
@ -28,12 +28,13 @@ block content
|
|||
if profileLinks.length
|
||||
ul.links
|
||||
each link in profileLinks
|
||||
li(title=profile.name + " on " + link.name, class=link.icon ? "has-icon" : "")
|
||||
a(href=link.link)
|
||||
if link.icon
|
||||
img(src=link.icon.url, alt=link.icon.name)
|
||||
else
|
||||
button.btn.btn-large.btn-inverse.flat-button= link.name
|
||||
if link.link && link.name
|
||||
li(title=profile.name + " on " + link.name, class=link.icon ? "has-icon" : "")
|
||||
a(href=link.link)
|
||||
if link.icon
|
||||
img(src=link.icon.url, alt=link.icon.name)
|
||||
else
|
||||
button.btn.btn-large.btn-inverse.flat-button= link.name
|
||||
|
||||
div= profile.city + ', ' + profile.country
|
||||
div= profile.visa
|
||||
|
@ -50,35 +51,41 @@ block content
|
|||
|
||||
.middle-column.full-height-column
|
||||
.sub-column
|
||||
h3= profile.name
|
||||
p= profile.shortDescription
|
||||
h3= profile.name || "Anonymous Developer"
|
||||
if profile.shortDescription
|
||||
p= profile.shortDescription
|
||||
|
||||
each skill in profile.skills
|
||||
code= skill
|
||||
span
|
||||
div.long-description!= marked(profile.longDescription)
|
||||
if profile.longDescription
|
||||
div.long-description!= marked(profile.longDescription)
|
||||
|
||||
if profile.work.length
|
||||
h3.experience-header
|
||||
img.header-icon(src="/images/pages/account/profile/work.png", alt="")
|
||||
span(data-i18n="account_profile.work_experience") Work Experience
|
||||
each job in profile.work
|
||||
div.experience-entry
|
||||
div.duration.pull-right= job.duration
|
||||
| #{job.role} at #{job.employer}
|
||||
.clearfix
|
||||
if job.description
|
||||
div!= marked(job.description)
|
||||
if job.role && job.employer
|
||||
div.experience-entry
|
||||
div.duration.pull-right= job.duration
|
||||
| #{job.role} at #{job.employer}
|
||||
.clearfix
|
||||
if job.description
|
||||
div!= marked(job.description)
|
||||
|
||||
if profile.education.length
|
||||
h3.experience-header
|
||||
img.header-icon(src="/images/pages/account/profile/education.png", alt="")
|
||||
span(data-i18n="account_profile.education") Education
|
||||
each school in profile.education
|
||||
div.experience-entry
|
||||
div.duration.pull-right= school.duration
|
||||
| #{school.degree} at #{school.school}
|
||||
.clearfix
|
||||
if school.degree && school.school
|
||||
div.experience-entry
|
||||
div.duration.pull-right= school.duration
|
||||
| #{school.degree} at #{school.school}
|
||||
.clearfix
|
||||
if school.description
|
||||
div!= marked(school.description)
|
||||
|
||||
if user.get('jobProfileNotes') || me.isAdmin()
|
||||
h3.experience-header(data-i18n="account_profile.our_notes") Our Notes
|
||||
|
@ -94,12 +101,13 @@ block content
|
|||
h3(data-i18n="account_profile.projects") Projects
|
||||
ul.projects
|
||||
each project in profile.projects
|
||||
li
|
||||
a(href=project.link)
|
||||
if project.picture
|
||||
.project-image(style="background-image: url(/file/" + project.picture + ")")
|
||||
p= project.name
|
||||
div!= marked(project.description)
|
||||
if project.name
|
||||
li
|
||||
a(href=project.link)
|
||||
if project.picture
|
||||
.project-image(style="background-image: url(/file/" + project.picture + ")")
|
||||
p= project.name
|
||||
div!= marked(project.description)
|
||||
|
||||
else
|
||||
.public-profile-container
|
||||
|
|
|
@ -39,7 +39,7 @@ block content
|
|||
if !isProduction
|
||||
.form-group.checkbox
|
||||
label(for="email", data-i18n="account_settings.admin") Admin
|
||||
input#admin(name="admin", type="checkbox", checked=me.get('permissions').indexOf('admin')>-1))
|
||||
input#admin(name="admin", type="checkbox", checked=me.get('permissions').indexOf('admin') != -1)
|
||||
|
||||
|
||||
#picture-pane.tab-pane
|
||||
|
|
|
@ -16,12 +16,8 @@ body
|
|||
ul.nav.navbar-nav
|
||||
li.play
|
||||
a.header-font(href='/play', data-i18n="nav.play") Levels
|
||||
li.editor
|
||||
a.header-font(href='/editor', data-i18n="nav.editor") Editor
|
||||
li.blog
|
||||
a.header-font(href='http://blog.codecombat.com/', data-i18n="nav.blog") Blog
|
||||
li.forum
|
||||
a.header-font(href='http://discourse.codecombat.com/', data-i18n="nav.forum") Forum
|
||||
li
|
||||
a.header-font(href='/community', data-i18n="nav.community") Community
|
||||
|
||||
.nav.navbar.navbar-fixed-top#top-nav
|
||||
.content.clearfix
|
||||
|
@ -34,9 +30,11 @@ body
|
|||
if me.get('anonymous') === false
|
||||
button.btn.btn-primary.navbuttontext.header-font#logout-button(data-i18n="login.log_out") Log Out
|
||||
a.btn.btn-primary.navbuttontext.header-font(href=me.get('jobProfile') ? "/account/profile/#{me.id}" : "/account/settings")
|
||||
div.navbuttontext-user-name
|
||||
| #{me.displayName()}
|
||||
i.icon-cog.icon-white.big
|
||||
div.navbuttontext-account(data-i18n="nav.account") Account
|
||||
if me.get('photoURL')
|
||||
img.account-settings-image(src=me.getPhotoURL(18), alt="")
|
||||
else
|
||||
span.glyphicon.glyphicon-user
|
||||
|
||||
else
|
||||
button.btn.btn-primary.navbuttontext.header-font(data-toggle="coco-modal", data-target="modal/signup", data-i18n="login.sign_up") Create Account
|
||||
|
@ -45,13 +43,8 @@ body
|
|||
ul(class='navbar-link-text').nav.navbar-nav.pull-right
|
||||
li.play
|
||||
a.header-font(href='/play', data-i18n="nav.play") Levels
|
||||
li.editor
|
||||
a.header-font(href='/editor', data-i18n="nav.editor") Editor
|
||||
li.blog
|
||||
a.header-font(href='http://blog.codecombat.com/', data-i18n="nav.blog") Blog
|
||||
li.forum
|
||||
a.header-font(href='http://discourse.codecombat.com/', data-i18n="nav.forum") Forum
|
||||
|
||||
li
|
||||
a.header-font(href='/community', data-i18n="nav.community") Community
|
||||
|
||||
block outer_content
|
||||
#outer-content-wrapper
|
||||
|
@ -65,7 +58,7 @@ body
|
|||
.footer.clearfix
|
||||
.content
|
||||
p.footer-link-text
|
||||
if pathname == "/"
|
||||
if pathname == "/" || (me.get('permissions') || []).indexOf('employer') != -1
|
||||
a(href='/employers', title='Home', tabindex=-1, data-i18n="nav.employers") Employers
|
||||
else
|
||||
a(href='/', title='Home', tabindex=-1, data-i18n="nav.home") Home
|
||||
|
@ -73,6 +66,9 @@ body
|
|||
a(href='/legal', title='Legal', tabindex=-1, data-i18n="nav.legal") Legal
|
||||
a(href='/about', title='About', tabindex=-1, data-i18n="nav.about") About
|
||||
a(title='Contact', tabindex=-1, data-toggle="coco-modal", data-target="modal/contact", data-i18n="nav.contact") Contact
|
||||
a(href='/editor', data-i18n="nav.editor") Editor
|
||||
a(href='http://blog.codecombat.com/', data-i18n="nav.blog") Blog
|
||||
a(href='http://discourse.codecombat.com/', data-i18n="nav.forum") Forum
|
||||
if me.isAdmin()
|
||||
a(href='/admin', data-i18n="nav.admin") Admin
|
||||
|
||||
|
|
88
app/templates/community.jade
Normal file
88
app/templates/community.jade
Normal file
|
@ -0,0 +1,88 @@
|
|||
extends /templates/base
|
||||
|
||||
block content
|
||||
|
||||
h1(data-i18n="community.main_title") CodeCombat Community
|
||||
|
||||
p There are dozens of ways you can get involved with CodeCombat. Check out the resources we've built, decide what sounds the most fun, and we look forward to working with you!
|
||||
|
||||
div
|
||||
|
||||
.community_columns
|
||||
|
||||
h2 Levels and Art
|
||||
|
||||
p We have built several tools that enable users to get not only edit, but also build new game content!
|
||||
|
||||
ul
|
||||
li
|
||||
a(href="/editor/level", data-i18n="community.level_editor")
|
||||
| : fork, edit, or build your own CodeCombat levels. New levels can be kept private or published to the community.
|
||||
li
|
||||
a(href="/editor/thang", data-i18n="editor.thang_title")
|
||||
| : modify or import new art assets for the game using our powerful editor.
|
||||
li
|
||||
a(href="/editor/article", data-i18n="editor.article_title")
|
||||
| : edit or create documentation used in CodeCombat levels.
|
||||
|
||||
p Right now most of our editing tools are very rough, but we are improving them constantly and welcome your feedback.
|
||||
|
||||
.community_columns
|
||||
|
||||
h2 Connect
|
||||
|
||||
p There are a bunch of ways you can connect with us and get involved in the ongoing development of CodeCombat:
|
||||
|
||||
ul
|
||||
|
||||
li We write about our progress and current projects on our
|
||||
a(href="http://blog.codecombat.com", data-i18n="nav.blog")
|
||||
| .
|
||||
li Participate in our active user community by checking out our
|
||||
a(href="http://discourse.codecombat.com", data-i18n="nav.forum")
|
||||
| .
|
||||
li For regular news about learning to code, games, and education, check out our
|
||||
a(href="https://www.facebook.com/codecombat", data-i18n="community.facebook")
|
||||
| .
|
||||
li For realtime status or to have a quick chat, follow us on
|
||||
a(href="https://twitter.com/CodeCombat", data-i18n="community.twitter")
|
||||
| .
|
||||
li Don't like Facebook? We're on
|
||||
a(href="https://plus.google.com/115285980638641924488/posts", data-i18n="community.gplus")
|
||||
| .
|
||||
li You can also find us in our
|
||||
a(href="http://www.hipchat.com/g3plnOKqa", data-i18n="editor.hipchat_url")
|
||||
|
||||
.community_columns
|
||||
|
||||
h2 Contribute
|
||||
|
||||
p Put your skills to use helping us teach the world to code. We have a lot of roles you can consider, and if we don't have a role for you, let us know:
|
||||
|
||||
ul
|
||||
|
||||
li
|
||||
a(href="/contribute#archmage", data-i18n="classes.archmage_title")
|
||||
| : contribute by writing code.
|
||||
li
|
||||
a(href="/contribute#artisan", data-i18n="classes.artisan_title")
|
||||
| : build new game levels.
|
||||
li
|
||||
a(href="/contribute#adventurer", data-i18n="classes.adventurer_title")
|
||||
| : test new game levels.
|
||||
li
|
||||
a(href="/contribute#scribe", data-i18n="classes.scribe_title")
|
||||
| : write educational documentation.
|
||||
li
|
||||
a(href="/contribute#diplomat", data-i18n="classes.diplomat_title")
|
||||
| : translate site content.
|
||||
li
|
||||
a(href="/contribute#ambassador", data-i18n="classes.ambassador_title")
|
||||
| : support our community of educators and coders.
|
||||
li
|
||||
a(href="/contribute#counselor", data-i18n="classes.counselor_title")
|
||||
| : offer your advice and business acumen to the founders.
|
||||
|
||||
| Check out the
|
||||
a(href="/contribute", data-i18n="nav.contribute")
|
||||
| page to find out more about the roles and how you can get started.
|
|
@ -34,11 +34,9 @@ block content
|
|||
hr
|
||||
|
||||
p
|
||||
span(data-i18n="editor.security_notice")
|
||||
| Many major features in these editors are not currently enabled by default.
|
||||
| As we improve the security of these systems, they will be made generally available.
|
||||
| If you'd like to use these features sooner,
|
||||
a(title='Contact', tabindex=-1, data-toggle="coco-modal", data-target="modal/contact", data-i18n="editor.contact_us") email us!
|
||||
span(data-i18n="editor.got_questions") Questions about using the CodeCombat editors?
|
||||
|
|
||||
a(title='Contact', tabindex=-1, data-toggle="coco-modal", data-target="modal/contact", data-i18n="editor.contact_us") Contact us!
|
||||
|
|
||||
span(data-i18n="editor.hipchat_prefix") You can also find us in our
|
||||
|
|
||||
|
|
|
@ -21,7 +21,6 @@ module.exports = class JobProfileView extends CocoView
|
|||
visibleSettings = @editableSettings.concat @readOnlySettings
|
||||
data = _.pick (me.get('jobProfile') ? {}), (value, key) => key in visibleSettings
|
||||
data.name ?= (me.get('firstName') + ' ' + me.get('lastName')).trim() if me.get('firstName')
|
||||
console.log 'schema?', me.schema()
|
||||
schema = _.cloneDeep me.schema().properties.jobProfile
|
||||
schema.properties = _.pick schema.properties, (value, key) => key in visibleSettings
|
||||
schema.required = _.intersection schema.required, visibleSettings
|
||||
|
@ -42,10 +41,56 @@ module.exports = class JobProfileView extends CocoView
|
|||
@jobProfileTreema = @$el.find('#job-profile-treema').treema treemaOptions
|
||||
@jobProfileTreema.build()
|
||||
@jobProfileTreema.open()
|
||||
@updateProgress()
|
||||
|
||||
onJobProfileChanged: (e) =>
|
||||
@hasEditedProfile = true
|
||||
@trigger 'change'
|
||||
@updateProgress()
|
||||
|
||||
updateProgress: ->
|
||||
completed = 0
|
||||
totalWeight = 0
|
||||
next = null
|
||||
for metric in metrics = @getProgressMetrics()
|
||||
done = metric.fn()
|
||||
completed += metric.weight ? 1 if done
|
||||
totalWeight += metric.weight
|
||||
next = metric.name unless next or done
|
||||
progress = Math.round 100 * completed / totalWeight
|
||||
bar = @$el.find('.profile-completion-progress .progress-bar')
|
||||
bar.css 'width', "#{progress}%"
|
||||
text = ""
|
||||
if progress > 19
|
||||
text = "#{progress}% complete"
|
||||
else if progress > 5
|
||||
text = "#{progress}%"
|
||||
bar.text text
|
||||
bar.parent().toggle Boolean progress
|
||||
@$el.find('.progress-next-item').text(next).toggle Boolean next
|
||||
|
||||
getProgressMetrics: ->
|
||||
return @progressMetrics if @progressMetrics
|
||||
schema = me.schema().properties.jobProfile
|
||||
jobProfile = @jobProfileTreema.data
|
||||
exists = (field) -> -> jobProfile[field]
|
||||
modified = (field) -> -> jobProfile[field] and jobProfile[field] isnt schema.properties[field].default
|
||||
listStarted = (field, subfields) -> -> jobProfile[field]?.length and _.every subfields, (subfield) -> jobProfile[field][0][subfield]
|
||||
@progressMetrics = [
|
||||
{name: "Mark yourself open to offers to show up in searches.", weight: 1, fn: modified 'active'}
|
||||
{name: "Specify your desired job title.", weight: 0, fn: exists 'jobTitle'}
|
||||
{name: "Provide your name.", weight: 1, fn: modified 'name'}
|
||||
{name: "Choose your city.", weight: 1, fn: modified 'city'}
|
||||
{name: "Pick your country.", weight: 0, fn: exists 'country'}
|
||||
{name: "List at least five skills.", weight: 2, fn: -> jobProfile.skills.length >= 5}
|
||||
{name: "Write a short description to summarize yourself at a glance.", weight: 2, fn: modified 'shortDescription'}
|
||||
{name: "Fill in your main description to sell yourself and describe the work you're looking for.", weight: 3, fn: modified 'longDescription'}
|
||||
{name: "List your work experience.", weight: 3, fn: listStarted 'work', ['role', 'employer']}
|
||||
{name: "Recount your educational ordeals.", weight: 3, fn: listStarted 'education', ['degree', 'school']}
|
||||
{name: "Show off up to three projects you've worked on.", weight: 3, fn: listStarted 'projects', ['name']}
|
||||
{name: "Add any personal or social links.", weight: 2, fn: listStarted 'links', ['link', 'name']}
|
||||
{name: "Add an optional professional photo.", weight: 2, fn: modified 'photoURL'}
|
||||
]
|
||||
|
||||
getData: ->
|
||||
return {} unless me.get('jobProfile') or @hasEditedProfile
|
||||
|
|
|
@ -3,6 +3,7 @@ template = require 'templates/account/settings'
|
|||
{me} = require('lib/auth')
|
||||
forms = require('lib/forms')
|
||||
User = require('models/User')
|
||||
LoginModalView = require 'views/modal/login_modal'
|
||||
|
||||
WizardSettingsView = require './wizard_settings_view'
|
||||
JobProfileView = require './job_profile_view'
|
||||
|
@ -45,6 +46,11 @@ module.exports = class SettingsView extends View
|
|||
@insertSubView @jobProfileView
|
||||
_.defer => @buildPictureTreema() # Not sure why, but the Treemas don't fully build without this if you reload the page.
|
||||
|
||||
afterInsert: ->
|
||||
super()
|
||||
if me.get('anonymous')
|
||||
@openModalView new LoginModalView()
|
||||
|
||||
chooseTab: (category) ->
|
||||
id = "##{category}-pane"
|
||||
pane = $(id, @$el)
|
||||
|
|
6
app/views/community_view.coffee
Normal file
6
app/views/community_view.coffee
Normal file
|
@ -0,0 +1,6 @@
|
|||
View = require 'views/kinds/RootView'
|
||||
template = require 'templates/community'
|
||||
|
||||
module.exports = class CommunityView extends View
|
||||
id: "community-view"
|
||||
template: template
|
|
@ -255,7 +255,7 @@ module.exports = class ThangsTabView extends View
|
|||
# @thangsTreema.deselectAll()
|
||||
|
||||
selectAddThang: (e) =>
|
||||
return unless e? and $(e.target).closest('.editor-level-thangs-tab-view').length
|
||||
return unless e? and $(e.target).closest('#editor-level-thangs-tab-view').length
|
||||
if e then target = $(e.target) else target = @$el.find('.add-thangs-palette') # pretend to click on background if no event
|
||||
return true if target.attr('id') is 'surface'
|
||||
target = target.closest('.add-thang-palette-icon')
|
||||
|
|
|
@ -26,7 +26,7 @@ module.exports = class ModelModal extends View
|
|||
treemaOptions =
|
||||
schema: schema
|
||||
data: data
|
||||
readOnly: true
|
||||
readOnly: false
|
||||
modelTreema = @$el.find(".model-treema[data-model-id='#{model.id}']").treema treemaOptions
|
||||
modelTreema?.build()
|
||||
modelTreema?.open()
|
||||
|
|
|
@ -46,7 +46,7 @@ module.exports = class LadderTabView extends CocoView
|
|||
return if @checked or (not window.FB) or (not window.gapi)
|
||||
@checked = true
|
||||
|
||||
@addSomethingToLoad("facebook_status")
|
||||
@addSomethingToLoad("facebook_status", 0) # This might not load ever, so we can't wait for it
|
||||
FB.getLoginStatus (response) =>
|
||||
@facebookStatus = response.status
|
||||
@loadFacebookFriends() if @facebookStatus is 'connected'
|
||||
|
@ -105,7 +105,7 @@ module.exports = class LadderTabView extends CocoView
|
|||
|
||||
gplusSessionStateLoaded: ->
|
||||
if application.gplusHandler.loggedIn
|
||||
@addSomethingToLoad("gplus_friends", 0) # this might not load ever, so we can't wait for it
|
||||
@addSomethingToLoad("gplus_friends", 0) # This might not load ever, so we can't wait for it
|
||||
application.gplusHandler.loadFriends @gplusFriendsLoaded
|
||||
|
||||
gplusFriendsLoaded: (friends) =>
|
||||
|
|
103
scripts/mail.coffee
Normal file
103
scripts/mail.coffee
Normal file
|
@ -0,0 +1,103 @@
|
|||
do (setupLodash = this) ->
|
||||
GLOBAL._ = require 'lodash'
|
||||
_.str = require 'underscore.string'
|
||||
_.mixin _.str.exports()
|
||||
|
||||
async = require 'async'
|
||||
|
||||
serverSetup = require '../server_setup'
|
||||
sendwithus = require '../server/sendwithus'
|
||||
User = require '../server/users/User.coffee'
|
||||
Level = require '../server/levels/Level.coffee'
|
||||
LevelSession = require '../server/levels/sessions/LevelSession.coffee'
|
||||
|
||||
alreadyEmailed = []
|
||||
|
||||
DEBUGGING = true
|
||||
|
||||
sendInitialRecruitingEmail = ->
|
||||
leaderboards = [
|
||||
{slug: 'brawlwood', team: 'humans', limit: 55, name: "Brawlwood", original: "52d97ecd32362bc86e004e87", majorVersion: 0}
|
||||
{slug: 'brawlwood', team: 'ogres', limit: 40, name: "Brawlwood", original: "52d97ecd32362bc86e004e87", majorVersion: 0}
|
||||
{slug: 'dungeon-arena', team: 'humans', limit: 200, name: "Dungeon Arena", original: "53173f76c269d400000543c2", majorVersion: 0}
|
||||
{slug: 'dungeon-arena', team: 'ogres', limit: 150, name: "Dungeon Arena", original: "53173f76c269d400000543c2", majorVersion: 0}
|
||||
]
|
||||
async.waterfall [
|
||||
(callback) -> async.map leaderboards, grabSessions, callback
|
||||
(sessionLists, callback) -> async.map collapseSessions(sessionLists), grabUser, callback
|
||||
(users, callback) -> async.map users, emailUser, callback
|
||||
], (err, results) ->
|
||||
return console.log "Error:", err if err
|
||||
console.log "Looked at sending to #{results.length} users; sent to #{_.filter(results).length}."
|
||||
console.log "Sent to: ['#{(user.email for user in results when user).join('\', \'')}']"
|
||||
|
||||
grabSessions = (levelInfo, callback) ->
|
||||
queryParameters =
|
||||
level: {original: levelInfo.original, majorVersion: levelInfo.majorVersion}
|
||||
team: levelInfo.team
|
||||
submitted: true
|
||||
sortParameters = totalScore: -1
|
||||
selectString = 'totalScore creator'
|
||||
query = LevelSession
|
||||
.find(queryParameters)
|
||||
.limit(levelInfo.limit)
|
||||
.sort(sortParameters)
|
||||
.select(selectString)
|
||||
.lean()
|
||||
query.exec (err, sessions) ->
|
||||
return callback err if err
|
||||
for session, rank in sessions
|
||||
session.levelInfo = levelInfo
|
||||
session.rank = rank + 1
|
||||
callback null, sessions
|
||||
|
||||
collapseSessions = (sessionLists) ->
|
||||
userRanks = {}
|
||||
for sessionList in sessionLists
|
||||
for session in sessionList
|
||||
ranks = userRanks[session.creator] ? []
|
||||
ranks.push session
|
||||
userRanks[session.creator] = _.sortBy ranks, 'rank'
|
||||
topSessions = []
|
||||
for userID, ranks of userRanks
|
||||
topSessions.push ranks[0]
|
||||
topSessions
|
||||
|
||||
grabUser = (session, callback) ->
|
||||
findParameters = _id: session.creator
|
||||
selectString = 'email emailSubscriptions name jobProfile'
|
||||
query = User
|
||||
.findOne(findParameters)
|
||||
.select(selectString)
|
||||
.lean()
|
||||
query.exec (err, user) ->
|
||||
return callback err if err
|
||||
user.session = session
|
||||
callback null, user
|
||||
|
||||
totalEmailsSent = 0
|
||||
emailUser = (user, callback) ->
|
||||
return callback null, false if user.emails?.recruiting?.enabled is false # TODO: later, obey also "announcements" when that's untangled
|
||||
return callback null, false if user.email in alreadyEmailed
|
||||
return callback null, false if DEBUGGING and (totalEmailsSent > 1 or Math.random() > 0.1)
|
||||
++totalEmailsSent
|
||||
name = if user.firstName and user.lastName then "#{user.firstName}" else user.name
|
||||
name = "Wizard" if not name or name is "Anoner"
|
||||
team = user.session.levelInfo.team
|
||||
team = team.substr(0, team.length - 1)
|
||||
context =
|
||||
email_id: sendwithus.templates.one_time_recruiting_email
|
||||
recipient:
|
||||
address: if DEBUGGING then 'nick@codecombat.com' else user.email
|
||||
name: name
|
||||
email_data:
|
||||
name: name
|
||||
level_name: user.session.levelInfo.name
|
||||
place: "##{user.session.rank}" # like "#31"
|
||||
level_race: team
|
||||
sendwithus.api.send context, (err, result) ->
|
||||
return callback err if err
|
||||
callback null, user
|
||||
|
||||
serverSetup.connectToDatabase()
|
||||
sendInitialRecruitingEmail()
|
|
@ -104,7 +104,7 @@ module.exports = class Handler
|
|||
query = { 'target.original': mongoose.Types.ObjectId(id), status: req.query.status or 'pending' }
|
||||
Patch.find(query).sort('-created').exec (err, patches) =>
|
||||
return @sendDatabaseError(res, err) if err
|
||||
patches = (patch.toObject() for patch in patches)
|
||||
patches = (patch.toObject() for patch in patches)
|
||||
@sendSuccess(res, patches)
|
||||
|
||||
setWatching: (req, res, id) ->
|
||||
|
@ -168,8 +168,6 @@ module.exports = class Handler
|
|||
aggregate = $match: query
|
||||
@modelClass.aggregate(aggregate).project(selectString).limit(FETCH_LIMIT).sort(sort).exec (err, results) =>
|
||||
return @sendDatabaseError(res, err) if err
|
||||
for doc in results
|
||||
return @sendUnauthorizedError(res) unless @hasAccessToDocument(req, doc)
|
||||
res.send(results)
|
||||
res.end()
|
||||
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
config = require '../server_config'
|
||||
sendwithusAPI = require 'sendwithus'
|
||||
swuAPIKey = config.mail.sendwithusAPIKey
|
||||
queues = require './commons/queue'
|
||||
|
||||
module.exports.setupRoutes = (app) ->
|
||||
return
|
||||
|
||||
|
||||
debug = not config.isProduction
|
||||
module.exports.api = new sendwithusAPI swuAPIKey, debug
|
||||
if config.unittest
|
||||
|
@ -16,3 +14,4 @@ module.exports.templates =
|
|||
ladder_update_email: 'JzaZxf39A4cKMxpPZUfWy4'
|
||||
patch_created: 'tem_xhxuNosLALsizTNojBjNcL'
|
||||
change_made_notify_watcher: 'tem_7KVkfmv9SZETb25dtHbUtG'
|
||||
one_time_recruiting_email: 'tem_mdFMgtcczHKYu94Jmq68j8'
|
||||
|
|
|
@ -14,7 +14,7 @@ LevelSessionHandler = require '../levels/sessions/level_session_handler'
|
|||
serverProperties = ['passwordHash', 'emailLower', 'nameLower', 'passwordReset']
|
||||
privateProperties = [
|
||||
'permissions', 'email', 'firstName', 'lastName', 'gender', 'facebookID',
|
||||
'gplusID', 'music', 'volume', 'aceConfig'
|
||||
'gplusID', 'music', 'volume', 'aceConfig', 'employerAt'
|
||||
]
|
||||
candidateProperties = [
|
||||
'jobProfile', 'jobProfileApproved', 'jobProfileNotes'
|
||||
|
@ -47,7 +47,7 @@ UserHandler = class UserHandler extends Handler
|
|||
delete obj[prop] for prop in serverProperties
|
||||
includePrivates = req.user and (req.user.isAdmin() or req.user._id.equals(document._id))
|
||||
delete obj[prop] for prop in privateProperties unless includePrivates
|
||||
includeCandidate = includePrivates or (obj.jobProfileApproved and req.user and ('employer' in (req.user.permissions ? [])))
|
||||
includeCandidate = includePrivates or (obj.jobProfileApproved and req.user and ('employer' in (req.user.get('permissions') ? [])) and @employerCanViewCandidate req.user, obj)
|
||||
delete obj[prop] for prop in candidateProperties unless includeCandidate
|
||||
return obj
|
||||
|
||||
|
@ -259,13 +259,15 @@ UserHandler = class UserHandler extends Handler
|
|||
authorized = req.user.isAdmin() or ('employer' in req.user.get('permissions'))
|
||||
since = (new Date((new Date()) - 2 * 30.4 * 86400 * 1000)).toISOString()
|
||||
query = {'jobProfile.active': true, 'jobProfile.updated': {$gt: since}}
|
||||
#query = {'jobProfile.updated': {$gt: since}}
|
||||
query.jobProfileApproved = true unless req.user.isAdmin()
|
||||
selection = 'jobProfile'
|
||||
selection += ' email' if authorized
|
||||
selection += ' jobProfileApproved' if req.user.isAdmin()
|
||||
User.find(query).select(selection).exec (err, documents) =>
|
||||
return @sendDatabaseError(res, err) if err
|
||||
candidates = (@formatCandidate(authorized, doc) for doc in documents)
|
||||
candidates = (candidate for candidate in documents when @employerCanViewCandidate req.user, candidate.toObject())
|
||||
candidates = (@formatCandidate(authorized, candidate) for candidate in candidates)
|
||||
@sendSuccess(res, candidates)
|
||||
|
||||
formatCandidate: (authorized, document) ->
|
||||
|
@ -278,6 +280,16 @@ UserHandler = class UserHandler extends Handler
|
|||
obj.jobProfile = _.pick obj.jobProfile, subfields
|
||||
obj
|
||||
|
||||
employerCanViewCandidate: (employer, candidate) ->
|
||||
return true if employer.isAdmin()
|
||||
for job in candidate.jobProfile?.work ? []
|
||||
# TODO: be smarter about different ways to write same company names to ensure privacy.
|
||||
# We'll have to manually pay attention to how we set employer names for now.
|
||||
if job.employer?.toLowerCase() is employer.get('employerAt')?.toLowerCase()
|
||||
log.info "#{employer.get('name')} at #{employer.get('employerAt')} can't see #{candidate.jobProfile.name} because s/he worked there."
|
||||
return false if job.employer?.toLowerCase() is employer.get('employerAt')?.toLowerCase()
|
||||
true
|
||||
|
||||
buildGravatarURL: (user, size, fallback) ->
|
||||
emailHash = @buildEmailHash user
|
||||
fallback ?= "http://codecombat.com/file/db/thang.type/52a00d55cf1818f2be00000b/portrait.png"
|
||||
|
|
Loading…
Reference in a new issue