├── .editorconfig ├── .gitignore ├── .jshintrc ├── .meteor ├── .finished-upgraders ├── .gitignore ├── .id ├── cordova-plugins ├── packages ├── platforms ├── release └── versions ├── .travis.yml ├── History.md ├── README.md ├── README.nitrous.md ├── Roadmap.md ├── app-graphics ├── telescope-128.png ├── telescope-150.png ├── telescope-24.png ├── telescope-256.png ├── telescope-300.png └── telescope-48.png ├── client ├── helpers │ └── handlebars.js ├── main.html ├── main.js └── views │ ├── admin │ ├── settings_form.html │ └── settings_form.js │ ├── comments │ ├── comment_deleted.html │ ├── comment_edit.html │ ├── comment_edit.js │ ├── comment_form.html │ ├── comment_form.js │ ├── comment_item.html │ ├── comment_item.js │ ├── comment_list.html │ ├── comment_list.js │ ├── comment_reply.html │ └── comment_reply.js │ ├── common │ ├── css.html │ ├── css.js │ ├── footer.html │ ├── footer.js │ ├── layout.html │ ├── layout.js │ ├── message_item.html │ ├── message_item.js │ ├── messages.html │ └── messages.js │ ├── errors │ ├── already_logged_in.html │ ├── loading.html │ ├── loading.js │ ├── no_account.html │ ├── no_account.js │ ├── no_invite.html │ ├── no_invite.js │ ├── no_rights.html │ └── not_found.html │ ├── forms │ ├── quickFormTelescope.html │ ├── quickFormTelescope.js │ ├── urlCustomType.html │ └── urlCustomType.js │ ├── nav │ ├── admin_menu.html │ ├── admin_menu.js │ ├── menu_item.html │ ├── mobile_nav.html │ ├── mobile_nav.js │ ├── nav.html │ ├── nav.js │ ├── submit_button.html │ ├── user_menu.html │ ├── user_menu.js │ ├── views_menu.html │ └── views_menu.js │ ├── posts │ ├── after_post_item.html │ ├── before_post_item.html │ ├── modules │ │ ├── post_actions.html │ │ ├── post_actions.js │ │ ├── post_admin.html │ │ ├── post_admin.js │ │ ├── post_author.html │ │ ├── post_avatars.html │ │ ├── post_avatars.js │ │ ├── post_comments_link.html │ │ ├── post_content.html │ │ ├── post_content.js │ │ ├── post_discuss.html │ │ ├── post_domain.html │ │ ├── post_domain.js │ │ ├── post_info.html │ │ ├── post_info.js │ │ ├── post_rank.html │ │ ├── post_rank.js │ │ ├── post_title.html │ │ ├── post_title.js │ │ ├── post_upvote.html │ │ └── post_upvote.js │ ├── post_body.html │ ├── post_edit.html │ ├── post_edit.js │ ├── post_item.html │ ├── post_item.js │ ├── post_list │ │ ├── posts_list.html │ │ ├── posts_list.js │ │ ├── posts_list_incoming.html │ │ ├── posts_list_incoming.js │ │ ├── posts_load_more.html │ │ └── posts_load_more.js │ ├── post_page.html │ ├── post_page.js │ ├── post_submit.html │ └── post_submit.js │ └── users │ ├── account │ ├── user_account.html │ └── user_account.js │ ├── profile │ ├── user_comments.html │ ├── user_comments.js │ ├── user_downvoted_posts.html │ ├── user_downvoted_posts.js │ ├── user_info.html │ ├── user_info.js │ ├── user_posts.html │ ├── user_posts.js │ ├── user_upvoted_posts.html │ └── user_upvoted_posts.js │ ├── sandstorm_sign_in.html │ ├── sign_out.html │ ├── user_edit.html │ ├── user_edit.js │ ├── user_email.html │ ├── user_email.js │ ├── user_item.html │ ├── user_item.js │ ├── user_profile.html │ ├── user_profile.js │ ├── users.html │ └── users.js ├── collections ├── comments.js ├── events.js ├── messages.js ├── posts.js ├── settings.js └── users.js ├── i18n ├── bg.i18n.json ├── de.i18n.json ├── en.i18n.json ├── es.i18n.json ├── fr.i18n.json ├── it.i18n.json ├── ru.i18n.json ├── tr.i18n.json └── zh-CN.i18n.json ├── lib ├── analytics.js ├── config │ ├── at_config.js │ ├── avatar.js │ └── debug.js ├── debug.js ├── events.js ├── helpers.js ├── parameters.js ├── publications.js ├── router │ ├── comments.js │ ├── config.js │ ├── filters.js │ ├── other.js │ ├── posts.js │ ├── server.js │ └── users.js ├── scoring.js ├── users.js ├── version.js └── vote.js ├── license.md ├── packages.json ├── packages ├── .gitignore ├── npm-container │ ├── .gitignore │ ├── index.js │ ├── package.js │ └── versions.json ├── telescope-api │ ├── .gitignore │ ├── lib │ │ └── server │ │ │ ├── api.js │ │ │ └── routes.js │ ├── package.js │ └── versions.json ├── telescope-base │ ├── .gitignore │ ├── lib │ │ ├── base.js │ │ ├── base_client.js │ │ └── base_server.js │ ├── package.js │ └── versions.json ├── telescope-blank │ ├── .gitignore │ ├── i18n │ │ └── en.i18n.json │ ├── lib │ │ ├── client │ │ │ ├── stylesheets │ │ │ │ └── custom.scss │ │ │ └── templates │ │ │ │ ├── customPostTitle.html │ │ │ │ ├── custom_template.html │ │ │ │ └── custom_template.js │ │ ├── custom_fields.js │ │ ├── hooks.js │ │ ├── main.js │ │ ├── routes.js │ │ ├── server │ │ │ └── publications.js │ │ ├── settings.js │ │ └── templates.js │ ├── package-tap.i18n │ ├── package.js │ └── versions.json ├── telescope-daily │ ├── .gitignore │ ├── i18n │ │ ├── de.i18n.json │ │ ├── en.i18n.json │ │ ├── es.i18n.json │ │ ├── fr.i18n.json │ │ ├── it.i18n.json │ │ └── zh-CN.i18n.json │ ├── lib │ │ ├── client │ │ │ ├── stylesheets │ │ │ │ └── daily.scss │ │ │ └── templates │ │ │ │ ├── after_day.html │ │ │ │ ├── before_day.html │ │ │ │ ├── posts_daily.html │ │ │ │ └── posts_daily.js │ │ ├── daily.js │ │ └── routes.js │ ├── package-tap.i18n │ ├── package.js │ └── versions.json ├── telescope-datetimepicker │ ├── .gitignore │ ├── autoform-bs-datetimepicker.html │ ├── autoform-bs-datetimepicker.js │ ├── bootstrap-collapse-transitions.js │ ├── datetimepicker.scss │ ├── fonts │ │ ├── glyphicons-halflings-regular.eot │ │ ├── glyphicons-halflings-regular.svg │ │ ├── glyphicons-halflings-regular.ttf │ │ └── glyphicons-halflings-regular.woff │ ├── package.js │ └── versions.json ├── telescope-email │ ├── .gitignore │ ├── .npm │ │ └── package │ │ │ ├── .gitignore │ │ │ ├── README │ │ │ └── npm-shrinkwrap.json │ ├── i18n │ │ ├── de.i18n.json │ │ ├── en.i18n.json │ │ ├── es.i18n.json │ │ ├── fr.i18n.json │ │ ├── it.i18n.json │ │ └── zh-CN.i18n.json │ ├── lib │ │ └── server │ │ │ ├── email.js │ │ │ ├── routes.js │ │ │ └── templates │ │ │ ├── emailAccountApproved.handlebars │ │ │ ├── emailInvite.handlebars │ │ │ ├── emailNewComment.handlebars │ │ │ ├── emailNewPendingPost.handlebars │ │ │ ├── emailNewPost.handlebars │ │ │ ├── emailNewReply.handlebars │ │ │ ├── emailNewUser.handlebars │ │ │ ├── emailPostApproved.handlebars │ │ │ ├── emailTest.handlebars │ │ │ └── emailWrapper.handlebars │ ├── package-tap.i18n │ ├── package.js │ └── versions.json ├── telescope-embedly │ ├── .gitignore │ ├── History.md │ ├── README.md │ ├── i18n │ │ ├── en.i18n.json │ │ └── fr.i18n.json │ ├── lib │ │ ├── client │ │ │ ├── autoform-postthumbnail.html │ │ │ ├── autoform-postthumbnail.js │ │ │ ├── post_thumbnail.html │ │ │ ├── post_thumbnail.js │ │ │ ├── post_thumbnail.scss │ │ │ ├── post_video.html │ │ │ └── post_video.js │ │ ├── embedly.js │ │ └── server │ │ │ └── get_embedly_data.js │ ├── package-tap.i18n │ ├── package.js │ └── versions.json ├── telescope-getting-started │ ├── .gitignore │ ├── content │ │ ├── customizing_telescope.md │ │ ├── deploying_telescope.md │ │ ├── getting_help.md │ │ ├── images │ │ │ ├── stackoverflow.png │ │ │ └── telescope.png │ │ ├── read_this_first.md │ │ └── removing_getting_started_posts.md │ ├── i18n │ │ └── en.i18n.json │ ├── lib │ │ ├── getting_started.js │ │ └── server │ │ │ └── dummy_content.js │ ├── package-tap.i18n │ ├── package.js │ └── versions.json ├── telescope-i18n │ ├── .gitignore │ ├── i18n.js │ ├── package.js │ └── versions.json ├── telescope-invites │ ├── .gitignore │ ├── i18n │ │ ├── de.i18n.json │ │ ├── en.i18n.json │ │ ├── es.i18n.json │ │ ├── fr.i18n.json │ │ ├── it.i18n.json │ │ └── zh-CN.i18n.json │ ├── lib │ │ ├── client │ │ │ └── templates │ │ │ │ ├── user_invites.html │ │ │ │ └── user_invites.js │ │ ├── invites.js │ │ └── server │ │ │ ├── invites.js │ │ │ └── publications.js │ ├── package-tap.i18n │ ├── package.js │ └── versions.json ├── telescope-kadira │ ├── .gitignore │ ├── lib │ │ ├── kadira-settings.js │ │ └── server │ │ │ └── kadira.js │ ├── package.js │ └── versions.json ├── telescope-lib │ ├── .gitignore │ ├── lib │ │ ├── autolink.js │ │ ├── client │ │ │ └── jquery.exists.js │ │ ├── deep.js │ │ ├── deep_extend.js │ │ ├── lib.js │ │ └── permissions.js │ ├── package.js │ └── versions.json ├── telescope-module-share │ ├── .gitignore │ ├── lib │ │ ├── client │ │ │ ├── post_share.html │ │ │ ├── post_share.js │ │ │ └── post_share.scss │ │ └── share.js │ ├── package.js │ └── versions.json ├── telescope-newsletter │ ├── .gitignore │ ├── .npm │ │ └── package │ │ │ ├── .gitignore │ │ │ ├── README │ │ │ └── npm-shrinkwrap.json │ ├── History.md │ ├── README.md │ ├── i18n │ │ ├── de.i18n.json │ │ ├── en.i18n.json │ │ ├── es.i18n.json │ │ ├── fr.i18n.json │ │ ├── it.i18n.json │ │ └── zh-CN.i18n.json │ ├── lib │ │ ├── client │ │ │ ├── stylesheets │ │ │ │ └── newsletter_banner.scss │ │ │ └── templates │ │ │ │ ├── newsletter_banner.html │ │ │ │ └── newsletter_banner.js │ │ ├── newsletter.js │ │ └── server │ │ │ ├── campaign.js │ │ │ ├── cron.js │ │ │ ├── mailchimp.js │ │ │ ├── routes.js │ │ │ └── templates │ │ │ ├── emailDigest.handlebars │ │ │ ├── emailDigestConfirmation.handlebars │ │ │ └── emailPostItem.handlebars │ ├── package-tap.i18n │ └── package.js ├── telescope-notifications │ ├── .gitignore │ ├── i18n │ │ ├── de.i18n.json │ │ ├── en.i18n.json │ │ ├── es.i18n.json │ │ ├── fr.i18n.json │ │ ├── it.i18n.json │ │ └── zh-CN.i18n.json │ ├── lib │ │ ├── client │ │ │ └── templates │ │ │ │ ├── notification_item.html │ │ │ │ ├── notification_item.js │ │ │ │ ├── notification_new_comment.html │ │ │ │ ├── notification_new_reply.html │ │ │ │ ├── notification_post_approved.html │ │ │ │ ├── notifications_menu.html │ │ │ │ ├── notifications_menu.js │ │ │ │ ├── unsubscribe.html │ │ │ │ └── unsubscribe.js │ │ ├── herald.js │ │ ├── notifications.js │ │ └── server │ │ │ ├── notifications-server.js │ │ │ └── routes.js │ ├── package-tap.i18n │ ├── package.js │ └── versions.json ├── telescope-post-by-feed │ ├── .gitignore │ ├── .npm │ │ └── package │ │ │ ├── .gitignore │ │ │ ├── README │ │ │ └── npm-shrinkwrap.json │ ├── i18n │ │ └── en.i18n.json │ ├── lib │ │ ├── client │ │ │ ├── routes.js │ │ │ ├── scss │ │ │ │ └── feeds.scss │ │ │ └── templates │ │ │ │ ├── feed_item.html │ │ │ │ ├── feed_item.js │ │ │ │ ├── feeds.html │ │ │ │ └── feeds.js │ │ ├── feeds.js │ │ └── server │ │ │ ├── cron.js │ │ │ ├── fetch_feeds.js │ │ │ └── publications.js │ ├── package-tap.i18n │ ├── package.js │ └── versions.json ├── telescope-releases │ ├── .gitignore │ ├── i18n │ │ └── en.i18n.json │ ├── lib │ │ ├── client │ │ │ ├── scss │ │ │ │ └── releases.scss │ │ │ └── templates │ │ │ │ ├── current_release.html │ │ │ │ └── current_release.js │ │ ├── releases.js │ │ └── server │ │ │ ├── import_releases.js │ │ │ └── publications.js │ ├── package-tap.i18n │ ├── package.js │ ├── releases │ │ ├── 0.11.0.md │ │ ├── 0.11.1.md │ │ ├── 0.12.0.md │ │ ├── 0.13.0.md │ │ └── 0.14.0.md │ └── versions.json ├── telescope-rss │ ├── .gitignore │ ├── .npm │ │ └── package │ │ │ ├── .gitignore │ │ │ ├── README │ │ │ └── npm-shrinkwrap.json │ ├── lib │ │ └── server │ │ │ ├── routes.js │ │ │ └── rss.js │ ├── package.js │ └── versions.json ├── telescope-search │ ├── .gitignore │ ├── i18n │ │ ├── de.i18n.json │ │ ├── en.i18n.json │ │ ├── es.i18n.json │ │ ├── fr.i18n.json │ │ ├── it.i18n.json │ │ ├── tr.i18n.json │ │ └── zh-CN.i18n.json │ ├── lib │ │ ├── client │ │ │ ├── css │ │ │ │ └── search.css │ │ │ ├── routes.js │ │ │ └── views │ │ │ │ ├── search.html │ │ │ │ ├── search.js │ │ │ │ ├── search_logs.html │ │ │ │ └── search_logs.js │ │ ├── search.js │ │ └── server │ │ │ ├── log_search.js │ │ │ └── publications.js │ ├── package-tap.i18n │ ├── package.js │ └── versions.json ├── telescope-singleday │ ├── .gitignore │ ├── i18n │ │ ├── de.i18n.json │ │ ├── en.i18n.json │ │ ├── es.i18n.json │ │ ├── fr.i18n.json │ │ ├── it.i18n.json │ │ ├── tr.i18n.json │ │ └── zh-CN.i18n.json │ ├── lib │ │ ├── client │ │ │ └── templates │ │ │ │ ├── single_day.html │ │ │ │ ├── single_day.js │ │ │ │ ├── single_day_nav.html │ │ │ │ └── single_day_nav.js │ │ ├── routes.js │ │ └── singleday.js │ ├── package-tap.i18n │ ├── package.js │ └── versions.json ├── telescope-subscribe-to-posts │ ├── .gitignore │ ├── i18n │ │ └── en.i18n.json │ ├── lib │ │ ├── client │ │ │ ├── stylesheets │ │ │ │ └── subscribe-to-posts.scss │ │ │ └── templates │ │ │ │ ├── post_subscribe.html │ │ │ │ ├── post_subscribe.js │ │ │ │ ├── user_subscribed_posts.html │ │ │ │ └── user_subscribed_posts.js │ │ ├── server │ │ │ └── publications.js │ │ └── subscribe-to-posts.js │ ├── package-tap.i18n │ ├── package.js │ └── versions.json ├── telescope-tags │ ├── .gitignore │ ├── i18n │ │ ├── de.i18n.json │ │ ├── en.i18n.json │ │ ├── es.i18n.json │ │ ├── fr.i18n.json │ │ ├── it.i18n.json │ │ └── zh-CN.i18n.json │ ├── lib │ │ ├── categories.js │ │ ├── client │ │ │ ├── routes.js │ │ │ ├── scss │ │ │ │ └── categories.scss │ │ │ └── templates │ │ │ │ ├── categories.html │ │ │ │ ├── categories.js │ │ │ │ ├── categories_menu.html │ │ │ │ ├── categories_menu.js │ │ │ │ ├── category_item.html │ │ │ │ ├── category_item.js │ │ │ │ ├── post_categories.html │ │ │ │ └── post_categories.js │ │ ├── custom_fields.js │ │ ├── hooks.js │ │ └── server │ │ │ └── publications.js │ ├── package-tap.i18n │ ├── package.js │ └── versions.json ├── telescope-theme-base │ ├── .gitignore │ ├── lib │ │ └── client │ │ │ └── scss │ │ │ ├── global │ │ │ ├── _forms.scss │ │ │ ├── _links.scss │ │ │ ├── _main.scss │ │ │ ├── _markdown.scss │ │ │ ├── _tables.scss │ │ │ └── _typography.scss │ │ │ ├── includes │ │ │ ├── _breakpoints.scss │ │ │ ├── _colors.scss │ │ │ └── _mixins.scss │ │ │ ├── screen.scss │ │ │ └── specific │ │ │ ├── _avatars.scss │ │ │ ├── _dropdown.scss │ │ │ ├── _errors.scss │ │ │ ├── _header.scss │ │ │ ├── _layout.scss │ │ │ ├── _loading.scss │ │ │ ├── _mobile_nav.scss │ │ │ ├── _notifications.scss │ │ │ ├── _posts.scss │ │ │ └── _users.scss │ ├── package.js │ └── versions.json ├── telescope-theme-hubble │ ├── .gitignore │ ├── lib │ │ ├── client │ │ │ └── scss │ │ │ │ ├── modules │ │ │ │ ├── _accounts.scss │ │ │ │ ├── _banners.scss │ │ │ │ ├── _comments.scss │ │ │ │ ├── _dialogs.scss │ │ │ │ ├── _errors.scss │ │ │ │ ├── _icons.scss │ │ │ │ ├── _nav.scss │ │ │ │ ├── _posts.scss │ │ │ │ └── _user-profile.scss │ │ │ │ ├── partials │ │ │ │ ├── _colors.scss │ │ │ │ ├── _grid.scss │ │ │ │ ├── _icons.scss │ │ │ │ ├── _mixins.scss │ │ │ │ ├── _tooltips.scss │ │ │ │ └── _typography.scss │ │ │ │ └── screen.scss │ │ └── hubble.js │ ├── package.js │ └── versions.json └── telescope-update-prompt │ ├── .gitignore │ ├── lib │ ├── client │ │ ├── templates │ │ │ ├── update_banner.css │ │ │ ├── update_banner.html │ │ │ └── update_banner.js │ │ └── update.js │ └── server │ │ └── phone_home.js │ ├── package.js │ └── versions.json ├── project-tap.i18n ├── public └── img │ ├── bg-black.png │ ├── bg-black@2x.png │ ├── bg-header.png │ ├── bg-header@2x.png │ ├── bg.png │ ├── bg@2x.png │ ├── default-avatar.png │ ├── favicon.ico │ ├── loading-balls.svg │ ├── loading.gif │ ├── loading.svg │ ├── logo.png │ ├── logo@2x.png │ ├── telescope-logo.png │ ├── telescope-logo2.png │ ├── telescope-logo@2x.png │ └── thegrid.svg ├── sandstorm-pkgdef.capnp ├── scss.json ├── server ├── migrations.js ├── publications │ ├── posts_list.js │ ├── settings.js │ ├── single_comment.js │ ├── single_post.js │ ├── user_profile.js │ ├── users.js │ └── users_dashboard.js ├── scoring.js ├── start.js ├── start_cron.js ├── testing.js └── users.js ├── testing.settings.json └── tests └── jasmine ├── client └── unit │ ├── commentItemSpec.js │ └── navSpec.js └── server └── integration └── packages └── telescope-lib └── permissionsSpec.js /.editorconfig: -------------------------------------------------------------------------------- 1 | # editorconfig.org 2 | 3 | root = true 4 | 5 | [*.{js,html}] 6 | 7 | charset = utf-8 8 | end_of_line = lf 9 | indent_brace_style = 1TBS 10 | indent_size = 2 11 | indent_style = space 12 | insert_final_newline = true 13 | max_line_length = 80 14 | quote_type = auto 15 | spaces_around_operators = true 16 | trim_trailing_whitespace = true 17 | 18 | [*.md] 19 | 20 | trim_trailing_whitespace = false 21 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | npm-debug.log 2 | *.scssc 3 | .sass-cache/* 4 | .DS_Store 5 | *-ck.js 6 | providers_secret.js 7 | *.sublime-project 8 | 9 | *.sublime-workspace 10 | codekit-config.json 11 | 12 | config.rb 13 | 14 | deploy.sh 15 | 16 | .demeteorized 17 | 18 | dump/ 19 | dump/* 20 | 21 | settings.json 22 | settings.json.not-used 23 | .idea 24 | 25 | scratch 26 | 27 | .deploy 28 | .deploy/* 29 | ### Meteor template 30 | .meteor/local 31 | .meteor/meteorite 32 | mup.json 33 | .meteor-spk 34 | -------------------------------------------------------------------------------- /.meteor/.finished-upgraders: -------------------------------------------------------------------------------- 1 | # This file contains information which helps Meteor properly upgrade your 2 | # app when you run 'meteor update'. You should check it into version control 3 | # with your project. 4 | 5 | notices-for-0.9.0 6 | notices-for-0.9.1 7 | 0.9.4-platform-file 8 | -------------------------------------------------------------------------------- /.meteor/.gitignore: -------------------------------------------------------------------------------- 1 | local 2 | meteorite 3 | -------------------------------------------------------------------------------- /.meteor/.id: -------------------------------------------------------------------------------- 1 | # This file contains a token that is unique to your project. 2 | # Check it into your repository along with the rest of this directory. 3 | # It can be used for purposes such as: 4 | # - ensuring you don't accidentally deploy one app on top of another 5 | # - providing package authors with aggregated statistics 6 | 7 | 4ibiemui4bqn1j744h7 8 | -------------------------------------------------------------------------------- /.meteor/cordova-plugins: -------------------------------------------------------------------------------- 1 | 2 | -------------------------------------------------------------------------------- /.meteor/platforms: -------------------------------------------------------------------------------- 1 | server 2 | browser 3 | -------------------------------------------------------------------------------- /.meteor/release: -------------------------------------------------------------------------------- 1 | METEOR@1.0.2.1 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "0.10" 4 | before_install: 5 | - curl https://install.meteor.com | /bin/sh 6 | 7 | before_script: 8 | - export DISPLAY=:99.0 9 | - sh -e /etc/init.d/xvfb start 10 | # Add testing package since it's not currently enabled in Telescope 11 | - printf "sanjo:jasmine@0.11.0" >> .meteor/packages 12 | 13 | script: 14 | - JASMINE_BROWSER=Firefox meteor --test -------------------------------------------------------------------------------- /README.nitrous.md: -------------------------------------------------------------------------------- 1 | # Setup for Nitrous.IO 2 | 3 | Before you can run this project, you will need to install Meteor with Autoparts (open-source package manager built specifically for Nitrous.IO boxes). 4 | 5 | Run the following commands in the Terminal below: 6 | 7 | 1. `cd ~/workspace/Telescope/` 8 | 2. `parts install meteor` 9 | 3. `meteor -p 0.0.0.0:3000` 10 | 11 | Usually you would just run `meteor`, but for nitrous environment host `0.0.0.0` is required. 12 | 13 | To preview the app, go to the "Preview Menu" and click "Port 3000" 14 | -------------------------------------------------------------------------------- /app-graphics/telescope-128.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/app-graphics/telescope-128.png -------------------------------------------------------------------------------- /app-graphics/telescope-150.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/app-graphics/telescope-150.png -------------------------------------------------------------------------------- /app-graphics/telescope-24.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/app-graphics/telescope-24.png -------------------------------------------------------------------------------- /app-graphics/telescope-256.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/app-graphics/telescope-256.png -------------------------------------------------------------------------------- /app-graphics/telescope-300.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/app-graphics/telescope-300.png -------------------------------------------------------------------------------- /app-graphics/telescope-48.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/app-graphics/telescope-48.png -------------------------------------------------------------------------------- /client/main.html: -------------------------------------------------------------------------------- 1 | 2 | Loading... 3 | 4 | 5 | 6 | 7 | -------------------------------------------------------------------------------- /client/main.js: -------------------------------------------------------------------------------- 1 | // Session variables 2 | Session.set('postsLimit', getSetting('postsPerPage', 10)); 3 | 4 | // Sort postModules array position using modulePositions as index 5 | postModules = _.sortBy(postModules, 'order'); 6 | 7 | postHeading = _.sortBy(postHeading, 'order'); 8 | 9 | postMeta = _.sortBy(postMeta, 'order'); 10 | 11 | Meteor.startup(function () { 12 | $('#rss-link').attr('title', i18n.t('new_posts')); 13 | }); 14 | 15 | // AutoForm.debug(); -------------------------------------------------------------------------------- /client/views/admin/settings_form.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/admin/settings_form.js: -------------------------------------------------------------------------------- 1 | AutoForm.hooks({ 2 | updateSettingsForm: { 3 | 4 | before: { 5 | update: function(docId, modifier, template) { 6 | template.$('button[type=submit]').addClass('loading'); 7 | return modifier; 8 | } 9 | }, 10 | 11 | onSuccess: function(operation, result, template) { 12 | template.$('button[type=submit]').removeClass('loading'); 13 | }, 14 | 15 | onError: function(operation, result, template) { 16 | template.$('button[type=submit]').removeClass('loading'); 17 | } 18 | 19 | }, 20 | insertSettingsForm: { 21 | 22 | before: { 23 | insert: function(doc, template) { 24 | template.$('button[type=submit]').addClass('loading'); 25 | return doc; 26 | } 27 | }, 28 | 29 | onSuccess: function(operation, result, template) { 30 | template.$('button[type=submit]').removeClass('loading'); 31 | }, 32 | 33 | onError: function(operation, result, template) { 34 | template.$('button[type=submit]').removeClass('loading'); 35 | } 36 | 37 | } 38 | }); -------------------------------------------------------------------------------- /client/views/comments/comment_deleted.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/comments/comment_edit.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/comments/comment_edit.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('comment_edit')].events({ 2 | 'click input[type=submit]': function(e, instance){ 3 | var comment = this; 4 | var content = instance.$('#body').val(); 5 | 6 | e.preventDefault(); 7 | 8 | if(!Meteor.user()) 9 | throw i18n.t('you_must_be_logged_in'); 10 | 11 | Comments.update(comment._id, { 12 | $set: { 13 | body: content 14 | } 15 | }); 16 | 17 | trackEvent("edit comment", {'postId': comment.postId, 'commentId': comment._id}); 18 | Router.go('post_page_comment', {_id: comment.postId, commentId: comment._id}); 19 | }, 20 | 'click .delete-link': function(e){ 21 | var comment = this; 22 | 23 | e.preventDefault(); 24 | 25 | if(confirm(i18n.t("are_you_sure"))){ 26 | Meteor.call('removeComment', comment._id); 27 | Router.go('post_page', {_id: comment.postId}); 28 | flashMessage("Your comment has been deleted.", "success"); 29 | } 30 | } 31 | }); 32 | -------------------------------------------------------------------------------- /client/views/comments/comment_form.html: -------------------------------------------------------------------------------- 1 | 17 | -------------------------------------------------------------------------------- /client/views/comments/comment_list.html: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /client/views/comments/comment_list.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('comment_list')].helpers({ 2 | comment_item: function () { 3 | return getTemplate('comment_item'); 4 | }, 5 | child_comments: function(){ 6 | var post = this; 7 | var comments = Comments.find({postId: post._id, parentCommentId: null}, {sort: {score: -1, postedAt: -1}}); 8 | return comments; 9 | }, 10 | threadModules: function () { 11 | return threadModules; 12 | }, 13 | getTemplate: function () { 14 | return getTemplate(this.template); 15 | } 16 | }); 17 | 18 | Template[getTemplate('comment_list')].rendered = function(){ 19 | // once all comments have been rendered, activate comment queuing for future real-time comments 20 | window.queueComments = true; 21 | }; -------------------------------------------------------------------------------- /client/views/comments/comment_reply.html: -------------------------------------------------------------------------------- 1 | 22 | -------------------------------------------------------------------------------- /client/views/comments/comment_reply.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('comment_reply')].helpers({ 2 | post_item: function () { 3 | return getTemplate('post_item'); 4 | }, 5 | comment_item: function () { 6 | return getTemplate('comment_item'); 7 | }, 8 | comment_form: function () { 9 | return getTemplate('comment_form'); 10 | }, 11 | post: function () { 12 | if(this.comment){ // XXX 13 | var post = Posts.findOne(this.comment.postId); 14 | return post; 15 | } 16 | } 17 | }); -------------------------------------------------------------------------------- /client/views/common/css.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('css')].helpers({ 2 | }); -------------------------------------------------------------------------------- /client/views/common/footer.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/common/footer.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('footer')].helpers({ 2 | footerCode: function(){ 3 | return getSetting('footerCode'); 4 | }, 5 | footerClass: function(){ 6 | return Session.get('isPostsList') ? 'absolute' : 'static'; 7 | }, 8 | footerModules: function () { 9 | return footerModules; 10 | }, 11 | getTemplate: function () { 12 | return getTemplate(this.template); 13 | } 14 | }); -------------------------------------------------------------------------------- /client/views/common/layout.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/common/layout.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('layout')].helpers({ 2 | mobile_nav: function () { 3 | return getTemplate('mobile_nav'); 4 | }, 5 | nav: function () { 6 | return getTemplate('nav'); 7 | }, 8 | messages: function () { 9 | return getTemplate('messages'); 10 | }, 11 | notifications: function () { 12 | return getTemplate('notifications'); 13 | }, 14 | footer: function () { 15 | return getTemplate('footer'); 16 | }, 17 | pageName : function(){ 18 | return getCurrentTemplate(); 19 | }, 20 | css: function () { 21 | return getTemplate('css'); 22 | }, 23 | heroModules: function () { 24 | return heroModules; 25 | }, 26 | getTemplate: function () { 27 | return getTemplate(this.template); 28 | } 29 | }); 30 | 31 | Template[getTemplate('layout')].created = function(){ 32 | Session.set('currentScroll', null); 33 | }; 34 | 35 | Template[getTemplate('layout')].rendered = function(){ 36 | if(currentScroll=Session.get('currentScroll')){ 37 | $('body').scrollTop(currentScroll); 38 | Session.set('currentScroll', null); 39 | } 40 | }; 41 | -------------------------------------------------------------------------------- /client/views/common/message_item.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/common/message_item.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('message_item')].helpers({ 2 | 3 | }); 4 | 5 | Template[getTemplate('message_item')].created = function(){ 6 | var messageId=this.data._id; 7 | Meteor.setTimeout(function(){ 8 | Messages.update(messageId, {$set: {seen:true}}); 9 | }, 100); 10 | }; -------------------------------------------------------------------------------- /client/views/common/messages.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/common/messages.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('messages')].helpers({ 2 | message_item: function () { 3 | return getTemplate('message_item'); 4 | }, 5 | messages: function(){ 6 | return Messages.find({show: true}); 7 | } 8 | }); -------------------------------------------------------------------------------- /client/views/errors/already_logged_in.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/errors/loading.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/errors/loading.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('loading')].helpers({ 2 | log: function () { 3 | console.log('loading…') 4 | } 5 | }); -------------------------------------------------------------------------------- /client/views/errors/no_account.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/errors/no_account.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('no_account')].helpers({ 2 | landingPageText: function(){ 3 | return getSetting("landingPageText"); 4 | } 5 | }); 6 | Template[getTemplate('no_account')].events({ 7 | 'click .twitter-button': function(){ 8 | Meteor.loginWithTwitter(function(){ 9 | Router.go('/'); 10 | }); 11 | } 12 | }); -------------------------------------------------------------------------------- /client/views/errors/no_invite.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/errors/no_invite.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('no_invite')].helpers({ 2 | afterSignupText: function(){ 3 | return getSetting("afterSignupText"); 4 | } 5 | }); -------------------------------------------------------------------------------- /client/views/errors/no_rights.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/errors/not_found.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/forms/urlCustomType.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/forms/urlCustomType.js: -------------------------------------------------------------------------------- 1 | AutoForm.addInputType("bootstrap-url", { 2 | template: "afBootstrapUrl", 3 | valueOut: function () { 4 | var url = this.val(); 5 | if(!!url) 6 | return (url.substring(0, 7) == "http://" || url.substring(0, 8) == "https://") ? url : "http://"+url; 7 | } 8 | }); 9 | 10 | Template.afBootstrapUrl_bootstrap3.helpers({ 11 | atts: function addFormControlAtts() { 12 | console.log(this) 13 | var atts = _.clone(this.atts); 14 | // Add bootstrap class 15 | atts = AutoForm.Utility.addClass(atts, "form-control"); 16 | return atts; 17 | } 18 | }); 19 | 20 | -------------------------------------------------------------------------------- /client/views/nav/admin_menu.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/nav/admin_menu.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('adminMenu')].helpers({ 2 | menuItem: function () { 3 | return getTemplate('menuItem'); 4 | }, 5 | menu: function () { 6 | return adminMenu; 7 | } 8 | }); -------------------------------------------------------------------------------- /client/views/nav/menu_item.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/nav/mobile_nav.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/nav/mobile_nav.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('mobile_nav')].helpers({ 2 | primaryNav: function () { 3 | return primaryNav; 4 | }, 5 | secondaryNav: function () { 6 | return secondaryNav; 7 | }, 8 | getTemplate: function () { 9 | return getTemplate(this).template; 10 | } 11 | }); 12 | 13 | Template[getTemplate('mobile_nav')].events({ 14 | 'click .dropdown-sub-level': function () { 15 | $('body').toggleClass('mobile-nav-open'); 16 | } 17 | }); 18 | 19 | Template[getTemplate('mobile_nav')].events({ 20 | 'click .dropdown-top-level': function (e) { 21 | e.preventDefault(); 22 | $(e.currentTarget).next().slideToggle('fast'); 23 | }, 24 | 'click .mobile-nav a': function (e) { 25 | if (e.target.className.indexOf('dropdown-top-level') == -1){ 26 | $('body').removeClass('mobile-nav-open'); 27 | } 28 | } 29 | }); -------------------------------------------------------------------------------- /client/views/nav/nav.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('nav')].helpers({ 2 | primaryNav: function () { 3 | return _.sortBy(primaryNav, 'order'); 4 | }, 5 | hasPrimaryNav: function () { 6 | return !!primaryNav.length; 7 | }, 8 | secondaryNav: function () { 9 | return _.sortBy(secondaryNav, 'order'); 10 | }, 11 | hasSecondaryNav: function () { 12 | return !!secondaryNav.length; 13 | }, 14 | dropdownClass: function () { 15 | return getThemeSetting('useDropdowns', true) ? 'has-dropdown' : 'no-dropdown'; 16 | }, 17 | getTemplate: function () { 18 | return getTemplate(this.template); 19 | }, 20 | site_title: function(){ 21 | return getSetting('title', "Telescope"); 22 | }, 23 | logo_url: function(){ 24 | return getSetting('logoUrl'); 25 | } 26 | }); 27 | 28 | Template[getTemplate('nav')].events({ 29 | 'click .mobile-menu-button': function(e){ 30 | e.preventDefault(); 31 | $('body').toggleClass('mobile-nav-open'); 32 | } 33 | }); -------------------------------------------------------------------------------- /client/views/nav/submit_button.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/nav/user_menu.html: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /client/views/nav/user_menu.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('userMenu')].helpers({ 2 | isLoggedIn: function () { 3 | return !!Meteor.user(); 4 | }, 5 | name: function () { 6 | return getDisplayName(Meteor.user()); 7 | }, 8 | profileUrl: function () { 9 | return Router.path('user_profile', {_idOrSlug: Meteor.user().slug}); 10 | }, 11 | userEditUrl: function () { 12 | return Router.path('user_edit', {slug: Meteor.user().slug}); 13 | } 14 | }); 15 | -------------------------------------------------------------------------------- /client/views/nav/views_menu.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/nav/views_menu.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('viewsMenu')].helpers({ 2 | menuItem: function () { 3 | return getTemplate('menuItem'); 4 | }, 5 | views: function () { 6 | return viewsMenu; 7 | } 8 | }); 9 | -------------------------------------------------------------------------------- /client/views/posts/after_post_item.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/posts/before_post_item.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/posts/modules/post_actions.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/posts/modules/post_actions.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('postActions')].helpers({ 2 | 3 | }); 4 | 5 | Template[getTemplate('postActions')].events({ 6 | 'click .toggle-actions-link': function(e, instance){ 7 | e.preventDefault(); 8 | var $post = $(e.target).parents('.post'); 9 | var h = $post.height(); 10 | if ($post.hasClass('show-actions')) { 11 | $post.height('auto'); 12 | $post.removeClass('show-actions'); 13 | } else { 14 | $post.height(h+'px'); 15 | $post.addClass('show-actions'); 16 | } 17 | } 18 | }); -------------------------------------------------------------------------------- /client/views/posts/modules/post_admin.html: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /client/views/posts/modules/post_admin.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('postAdmin')].helpers({ 2 | postsMustBeApproved: function () { 3 | return !!getSetting('requirePostsApproval'); 4 | }, 5 | isApproved: function(){ 6 | return this.status == STATUS_APPROVED; 7 | }, 8 | shortScore: function(){ 9 | return Math.floor(this.score*1000)/1000; 10 | } 11 | }); 12 | 13 | Template[getTemplate('postAdmin')].events({ 14 | 'click .approve-link': function(e, instance){ 15 | Meteor.call('approvePost', this); 16 | e.preventDefault(); 17 | }, 18 | 'click .unapprove-link': function(e, instance){ 19 | Meteor.call('unapprovePost', this); 20 | e.preventDefault(); 21 | } 22 | }); -------------------------------------------------------------------------------- /client/views/posts/modules/post_author.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/posts/modules/post_avatars.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/posts/modules/post_avatars.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('postAvatars')].helpers({ 2 | commenters: function () { 3 | // remove post author ID from commenters to avoid showing author's avatar again 4 | // limit to 4 commenters in case there's more 5 | // TODO: show a "..." sign or something 6 | return _.first(_.without(this.commenters, this.userId), 4); 7 | } 8 | }); -------------------------------------------------------------------------------- /client/views/posts/modules/post_comments_link.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/posts/modules/post_content.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/posts/modules/post_content.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('postContent')].helpers({ 2 | postThumbnail: function () { 3 | return postThumbnail; 4 | }, 5 | postHeading: function () { 6 | return postHeading; 7 | }, 8 | postMeta: function () { 9 | return postMeta; 10 | }, 11 | getTemplate: function () { 12 | return getTemplate(this.template); 13 | }, 14 | sourceLink: function(){ 15 | return !!this.url ? this.url : "/posts/"+this._id; 16 | }, 17 | current_domain: function(){ 18 | return "http://"+document.domain; 19 | }, 20 | timestamp: function(){ 21 | time = this.status == STATUS_APPROVED ? this.postedAt : this.createdAt; 22 | return moment(time).format("MMMM Do, h:mm:ss a"); 23 | }, 24 | userAvatar: function(){ 25 | // THIS FUNCTION IS DEPRECATED -- package bengott:avatar is used instead. 26 | var author = Meteor.users.findOne(this.userId, {reactive: false}); 27 | if(!!author) 28 | return getAvatarUrl(author); // ALSO DEPRECATED 29 | }, 30 | inactiveClass: function(){ 31 | return (isAdmin(Meteor.user()) && this.inactive) ? i18n.t('inactive') : ""; 32 | }, 33 | commentsDisplayText: function(){ 34 | return this.comments == 1 ? i18n.t('comment') : i18n.t('comments'); 35 | } 36 | }); -------------------------------------------------------------------------------- /client/views/posts/modules/post_discuss.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/posts/modules/post_domain.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/posts/modules/post_domain.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('postDomain')].helpers({ 2 | domain: function(){ 3 | var a = document.createElement('a'); 4 | a.href = this.url; 5 | return a.hostname; 6 | } 7 | }); -------------------------------------------------------------------------------- /client/views/posts/modules/post_info.html: -------------------------------------------------------------------------------- 1 | 11 | -------------------------------------------------------------------------------- /client/views/posts/modules/post_info.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('postInfo')].helpers({ 2 | pointsUnitDisplayText: function(){ 3 | return this.upvotes == 1 ? i18n.t('point') : i18n.t('points'); 4 | }, 5 | getTemplate: function() { 6 | return getTemplate("postAuthor"); 7 | } 8 | }); -------------------------------------------------------------------------------- /client/views/posts/modules/post_rank.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/posts/modules/post_rank.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('postRank')].helpers({ 2 | oneBasedRank: function(){ 3 | if (typeof this.rank !== 'undefined') { 4 | return this.rank + 1; 5 | } 6 | } 7 | }); -------------------------------------------------------------------------------- /client/views/posts/modules/post_title.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/posts/modules/post_title.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('postTitle')].helpers({ 2 | postLink: function(){ 3 | return !!this.url ? getOutgoingUrl(this.url) : "/posts/"+this._id; 4 | }, 5 | postTarget: function() { 6 | return !!this.url ? '_blank' : ''; 7 | } 8 | }); -------------------------------------------------------------------------------- /client/views/posts/modules/post_upvote.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/posts/modules/post_upvote.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('postUpvote')].helpers({ 2 | upvoted: function(){ 3 | var user = Meteor.user(); 4 | if(!user) return false; 5 | return _.include(this.upvoters, user._id); 6 | } 7 | }); 8 | 9 | Template[getTemplate('postUpvote')].events({ 10 | 'click .upvote-link': function(e, instance){ 11 | var post = this; 12 | e.preventDefault(); 13 | if(!Meteor.user()){ 14 | Router.go('atSignIn'); 15 | flashMessage(i18n.t("please_log_in_first"), "info"); 16 | } 17 | Meteor.call('upvotePost', post, function(error, result){ 18 | trackEvent("post upvoted", {'_id': post._id}); 19 | }); 20 | } 21 | }); 22 | -------------------------------------------------------------------------------- /client/views/posts/post_body.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/posts/post_edit.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/posts/post_item.html: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /client/views/posts/post_item.js: -------------------------------------------------------------------------------- 1 | var post = {}; 2 | 3 | Template[getTemplate('post_item')].created = function () { 4 | post = this.data; 5 | }; 6 | 7 | Template[getTemplate('post_item')].helpers({ 8 | postModules: function () { 9 | return postModules; 10 | }, 11 | getTemplate: function () { 12 | return getTemplate(this.template); 13 | }, 14 | moduleContext: function () { // not used for now 15 | var module = this; 16 | module.templateClass = camelToDash(this.template) + ' ' + this.position + ' cell'; 17 | module.post = post; 18 | return module; 19 | }, 20 | moduleClass: function () { 21 | return camelToDash(this.template) + ' post-module'; 22 | }, 23 | postClass: function () { 24 | var post = this; 25 | var postAuthorClass = "author-"+post.author; 26 | 27 | var postClass = postClassCallbacks.reduce(function(result, currentFunction) { 28 | return currentFunction(post, result); 29 | }, postAuthorClass); 30 | 31 | return postClass; 32 | } 33 | }); 34 | -------------------------------------------------------------------------------- /client/views/posts/post_list/posts_list.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/posts/post_list/posts_list_incoming.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/posts/post_list/posts_list_incoming.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('postsListIncoming')].events({ 2 | 'click .show-new': function(e, instance) { 3 | Session.set('listPopulatedAt', new Date()); 4 | } 5 | }); -------------------------------------------------------------------------------- /client/views/posts/post_list/posts_load_more.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/posts/post_list/posts_load_more.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('postsLoadMore')].helpers({ 2 | postsReady: function () { 3 | return this.postsReady; 4 | }, 5 | hasPosts: function () { 6 | return !!this.postsCursor.count(); 7 | } 8 | }); 9 | 10 | Template[getTemplate('postsLoadMore')].events({ 11 | 'click .more-button': function (event, instance) { 12 | event.preventDefault(); 13 | if (this.controllerInstance) { 14 | // controller is a template 15 | this.loadMoreHandler(this.controllerInstance); 16 | } else { 17 | // controller is router 18 | this.loadMoreHandler(); 19 | } 20 | } 21 | }); -------------------------------------------------------------------------------- /client/views/posts/post_page.html: -------------------------------------------------------------------------------- 1 | 13 | -------------------------------------------------------------------------------- /client/views/posts/post_page.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('post_page')].helpers({ 2 | post_item: function () { 3 | return getTemplate('post_item'); 4 | }, 5 | post_body: function () { 6 | return getTemplate('post_body'); 7 | }, 8 | comment_form: function () { 9 | return getTemplate('comment_form'); 10 | }, 11 | comment_list: function () { 12 | return getTemplate('comment_list'); 13 | } 14 | }); 15 | 16 | Template[getTemplate('post_page')].rendered = function(){ 17 | $('body').scrollTop(0); 18 | }; 19 | -------------------------------------------------------------------------------- /client/views/posts/post_submit.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/users/profile/user_comments.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/users/profile/user_downvoted_posts.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/users/profile/user_info.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('userInfo')].helpers({ 2 | canEditProfile: function() { 3 | var currentUser = Meteor.user(); 4 | return currentUser && (this._id == currentUser._id || isAdmin(currentUser)); 5 | }, 6 | createdAtFormatted: function() { 7 | return this.createdAt; 8 | }, 9 | canInvite: function() { 10 | // if the user is logged in, the target user hasn't been invited yet, invites are enabled, and user is not viewing their own profile 11 | return Meteor.user() && Meteor.user()._id != this._id && !isInvited(this) && invitesEnabled() && can.invite(Meteor.user()); 12 | }, 13 | inviteCount: function() { 14 | return Meteor.user().inviteCount; 15 | }, 16 | getTwitterName: function () { 17 | return getTwitterName(this); 18 | }, 19 | getGitHubName: function () { 20 | return getGitHubName(this); 21 | } 22 | }); 23 | 24 | Template[getTemplate('userInfo')].events({ 25 | 'click .invite-link': function(e, instance){ 26 | Meteor.call('inviteUser', instance.data.user._id); 27 | flashMessage('Thanks, user has been invited.', "success"); 28 | } 29 | }); 30 | -------------------------------------------------------------------------------- /client/views/users/profile/user_posts.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/users/profile/user_upvoted_posts.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/users/sandstorm_sign_in.html: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /client/views/users/sign_out.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/users/user_edit.html: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /client/views/users/user_edit.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('user_edit')].helpers({ 2 | userProfileEdit: function () { 3 | return userProfileEdit; 4 | }, 5 | getTemplate: function () { 6 | return getTemplate(this.template); 7 | } 8 | }); 9 | -------------------------------------------------------------------------------- /client/views/users/user_email.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /client/views/users/user_item.html: -------------------------------------------------------------------------------- 1 | 35 | -------------------------------------------------------------------------------- /client/views/users/user_profile.html: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /client/views/users/user_profile.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('user_profile')].helpers({ 2 | userProfileDisplay: function () { 3 | return userProfileDisplay; 4 | }, 5 | getTemplate: function () { 6 | return getTemplate(this.template); 7 | } 8 | }); -------------------------------------------------------------------------------- /client/views/users/users.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('users')].helpers({ 2 | user_item: function () { 3 | return getTemplate('user_item'); 4 | }, 5 | loadMoreUrl: function(){ 6 | var count = parseInt(Session.get('usersLimit')) + 20; 7 | return '/all-users/' + count + '?filterBy='+this.filterBy+'&sortBy='+this.sortBy; 8 | }, 9 | allPostsLoaded: function () { 10 | return false; 11 | //TODO: hide load more button when all users have been loaded 12 | }, 13 | activeClass: function (link) { 14 | if(link == this.filterBy || link == this.sortBy) 15 | return "active"; 16 | }, 17 | sortBy: function (parameter) { 18 | return "?filterBy="+this.filterBy+"&sortBy="+parameter; 19 | }, 20 | filterBy: function (parameter) { 21 | return "?filterBy="+parameter+"&sortBy="+this.sortBy; 22 | } 23 | }); -------------------------------------------------------------------------------- /collections/events.js: -------------------------------------------------------------------------------- 1 | var eventSchema = new SimpleSchema({ 2 | createdAt: { 3 | type: Date 4 | }, 5 | name: { 6 | type: String 7 | }, 8 | description: { 9 | type: String, 10 | optional: true 11 | }, 12 | unique: { 13 | type: Boolean, 14 | optional: true 15 | }, 16 | important: { // marking an event as important means it should never be erased 17 | type: Boolean, 18 | optional: true 19 | } 20 | }); 21 | 22 | 23 | Events = new Meteor.Collection('events'); 24 | Events.attachSchema(eventSchema); 25 | 26 | if (Meteor.isServer) { 27 | logEvent = function (event) { 28 | 29 | // if event is supposed to be unique, check if it has already been logged 30 | if (!!event.unique && !!Events.findOne({name: event.name})) { 31 | return 32 | } 33 | 34 | event.createdAt = new Date(); 35 | 36 | Events.insert(event); 37 | 38 | } 39 | } -------------------------------------------------------------------------------- /collections/messages.js: -------------------------------------------------------------------------------- 1 | if(Meteor.isClient){ 2 | // Local (client-only) collection 3 | Messages = new Meteor.Collection(null); 4 | 5 | flashMessage = function(message, type){ 6 | type = (typeof type === 'undefined') ? 'error': type; 7 | // Store errors in the 'Messages' local collection 8 | Messages.insert({message:message, type:type, seen: false, show:true}); 9 | }; 10 | 11 | clearSeenMessages = function(){ 12 | Messages.update({seen:true}, {$set: {show:false}}, {multi:true}); 13 | }; 14 | 15 | } -------------------------------------------------------------------------------- /lib/config/avatar.js: -------------------------------------------------------------------------------- 1 | Avatar.options = { 2 | fallbackType: 'initials', 3 | emailHashProperty: 'email_hash' 4 | }; 5 | -------------------------------------------------------------------------------- /lib/config/debug.js: -------------------------------------------------------------------------------- 1 | // SimpleSchema.debug = true; -------------------------------------------------------------------------------- /lib/debug.js: -------------------------------------------------------------------------------- 1 | clog = function (s) { 2 | if(getSetting('debug', false)) 3 | console.log(s); 4 | } -------------------------------------------------------------------------------- /lib/events.js: -------------------------------------------------------------------------------- 1 | trackEvent = function(event, properties){ 2 | // console.log('trackevent: ', event, properties); 3 | var properties= (typeof properties === 'undefined') ? {} : properties; 4 | //TODO 5 | // add event to an Events collection for logging and buffering purposes 6 | if(Meteor.isClient){ 7 | if(typeof mixpanel !== 'undefined' && typeof mixpanel.track !== 'undefined'){ 8 | mixpanel.track(event, properties); 9 | } 10 | if(typeof GoSquared !== 'undefined' && typeof GoSquared.DefaultTracker !== 'undefined'){ 11 | GoSquared.DefaultTracker.TrackEvent(event, JSON.stringify(properties)); 12 | } 13 | } 14 | }; -------------------------------------------------------------------------------- /lib/publications.js: -------------------------------------------------------------------------------- 1 | privacyOptions = { // true means exposed 2 | _id: true, 3 | commentCount: true, 4 | createdAt: true, 5 | email_hash: true, 6 | isInvited: true, 7 | karma: true, 8 | postCount: true, 9 | slug: true, 10 | username: true, 11 | 'profile.name': true, 12 | 'profile.notifications': true, 13 | 'profile.bio': true, 14 | 'profile.github': true, 15 | 'profile.site': true, 16 | 'profile.twitter': true, 17 | 'services.twitter.profile_image_url': true, 18 | 'services.facebook.id': true, 19 | 'services.twitter.screenName': true, 20 | 'services.github.screenName': true, // Github is not really used, but there are some mentions to it in the code 21 | 'votes.downvotedComments': true, 22 | 'votes.downvotedPosts': true, 23 | 'votes.upvotedComments': true, 24 | 'votes.upvotedPosts': true 25 | }; 26 | 27 | // minimum required properties to display avatars 28 | avatarOptions = { 29 | _id: true, 30 | email_hash: true, 31 | slug: true, 32 | username: true, 33 | 'profile.name': true, 34 | 'profile.github': true, 35 | 'profile.twitter': true, 36 | 'services.twitter.profile_image_url': true, 37 | 'services.facebook.id': true, 38 | 'services.twitter.screenName': true, 39 | 'services.github.screenName': true, // Github is not really used, but there are some mentions to it in the code 40 | } 41 | -------------------------------------------------------------------------------- /lib/router/comments.js: -------------------------------------------------------------------------------- 1 | // Controller for comment pages 2 | 3 | CommentPageController = RouteController.extend({ 4 | waitOn: function() { 5 | return [ 6 | coreSubscriptions.subscribe('singleCommentAndChildren', this.params._id), 7 | coreSubscriptions.subscribe('commentUsers', this.params._id), 8 | coreSubscriptions.subscribe('commentPost', this.params._id) 9 | ]; 10 | }, 11 | data: function() { 12 | return { 13 | comment: Comments.findOne(this.params._id) 14 | }; 15 | }, 16 | onAfterAction: function () { 17 | window.queueComments = false; 18 | }, 19 | fastRender: true 20 | }); 21 | 22 | Meteor.startup( function () { 23 | 24 | // Comment Reply 25 | 26 | Router.route('/comments/:_id', { 27 | name: 'comment_reply', 28 | template: getTemplate('comment_reply'), 29 | controller: CommentPageController, 30 | onAfterAction: function() { 31 | window.queueComments = false; 32 | } 33 | }); 34 | 35 | // Comment Edit 36 | 37 | Router.route('/comments/:_id/edit', { 38 | name: 'comment_edit', 39 | template: getTemplate('comment_edit'), 40 | controller: CommentPageController, 41 | onAfterAction: function() { 42 | window.queueComments = false; 43 | } 44 | }); 45 | 46 | }); -------------------------------------------------------------------------------- /lib/router/config.js: -------------------------------------------------------------------------------- 1 | Router.setTemplateNameConverter(function (str) { return str; }); 2 | 3 | preloadSubscriptions.push('settings'); 4 | preloadSubscriptions.push('currentUser'); 5 | 6 | Router.configure({ 7 | layoutTemplate: getTemplate('layout'), 8 | loadingTemplate: getTemplate('loading'), 9 | notFoundTemplate: getTemplate('notFound'), 10 | waitOn: function () { 11 | return _.map(preloadSubscriptions, function(sub){ 12 | // can either pass strings or objects with subName and subArguments properties 13 | if (typeof sub === 'object'){ 14 | Meteor.subscribe(sub.subName, sub.subArguments); 15 | }else{ 16 | Meteor.subscribe(sub); 17 | } 18 | }); 19 | } 20 | }); 21 | 22 | // adding common subscriptions that's need to be loaded on all the routes 23 | // notification does not included here since it is not much critical and 24 | // it might have considerable amount of docs 25 | if(Meteor.isServer) { 26 | FastRender.onAllRoutes(function() { 27 | var router = this; 28 | _.each(preloadSubscriptions, function(sub){ 29 | router.subscribe(sub); 30 | }); 31 | }); 32 | } 33 | -------------------------------------------------------------------------------- /lib/router/other.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function (){ 2 | 3 | // Settings 4 | 5 | Router.route('/settings', { 6 | name: 'settings', 7 | template: getTemplate('settingsForm'), 8 | data: function () { 9 | // we only have one set of settings for now 10 | return { 11 | hasSettings: !!Settings.find().count(), 12 | settings: Settings.findOne() 13 | } 14 | } 15 | }); 16 | 17 | // Loading (for testing purposes) 18 | 19 | Router.route('/loading', { 20 | name: 'loading', 21 | template: getTemplate('loading') 22 | }); 23 | 24 | // Toolbox 25 | 26 | Router.route('/toolbox', { 27 | name: 'toolbox', 28 | template: getTemplate('toolbox') 29 | }); 30 | 31 | }); -------------------------------------------------------------------------------- /lib/version.js: -------------------------------------------------------------------------------- 1 | telescopeVersion = "0.14.0"; -------------------------------------------------------------------------------- /license.md: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) [year] [fullname] 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. -------------------------------------------------------------------------------- /packages.json: -------------------------------------------------------------------------------- 1 | { 2 | } -------------------------------------------------------------------------------- /packages/.gitignore: -------------------------------------------------------------------------------- 1 | /bootstrap3-datepicker 2 | /npm-container -------------------------------------------------------------------------------- /packages/npm-container/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/npm-container/index.js: -------------------------------------------------------------------------------- 1 | Meteor.npmRequire = function(moduleName) { // 74 2 | var module = Npm.require(moduleName); // 75 3 | return module; // 76 4 | }; // 77 5 | // 78 6 | Meteor.require = function(moduleName) { // 79 7 | console.warn('Meteor.require is deprecated. Please use Meteor.npmRequire instead!'); // 80 8 | return Meteor.npmRequire(moduleName); // 81 9 | }; // 82 -------------------------------------------------------------------------------- /packages/npm-container/versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": [ 3 | [ 4 | "meteor", 5 | "1.1.3" 6 | ], 7 | [ 8 | "underscore", 9 | "1.0.1" 10 | ] 11 | ], 12 | "pluginDependencies": [], 13 | "toolVersion": "meteor-tool@1.0.36", 14 | "format": "1.0" 15 | } -------------------------------------------------------------------------------- /packages/telescope-api/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/telescope-api/lib/server/routes.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function () { 2 | 3 | Router.route('api', { 4 | where: 'server', 5 | path: '/api/:limit?', 6 | action: function() { 7 | var limit = parseInt(this.params.limit); 8 | this.response.write(serveAPI(limit)); 9 | this.response.end(); 10 | } 11 | }); 12 | 13 | }); -------------------------------------------------------------------------------- /packages/telescope-api/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({summary: "Telescope API package"}); 2 | 3 | Package.onUse(function (api) { 4 | 5 | api.use(['telescope-base', 'telescope-lib'], ['server']); 6 | 7 | api.add_files(['lib/server/api.js', 'lib/server/routes.js'], ['server']); 8 | 9 | api.export(['serveAPI']); 10 | 11 | }); -------------------------------------------------------------------------------- /packages/telescope-base/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/telescope-base/lib/base_client.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/packages/telescope-base/lib/base_client.js -------------------------------------------------------------------------------- /packages/telescope-base/lib/base_server.js: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/packages/telescope-base/lib/base_server.js -------------------------------------------------------------------------------- /packages/telescope-blank/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/telescope-blank/i18n/en.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "translation_key": "translation string", 3 | "customViewLink": "Custom View Link", 4 | "customAdminLink": "Custom Admin Link" 5 | } -------------------------------------------------------------------------------- /packages/telescope-blank/lib/client/stylesheets/custom.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/packages/telescope-blank/lib/client/stylesheets/custom.scss -------------------------------------------------------------------------------- /packages/telescope-blank/lib/client/templates/customPostTitle.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/telescope-blank/lib/client/templates/custom_template.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/telescope-blank/lib/client/templates/custom_template.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function () { 2 | 3 | Template[getTemplate('customTemplate')].helpers({ 4 | name: function () { 5 | return "Bruce Willis"; 6 | } 7 | }); 8 | 9 | }); 10 | -------------------------------------------------------------------------------- /packages/telescope-blank/lib/custom_fields.js: -------------------------------------------------------------------------------- 1 | // Custom Post Property 2 | 3 | var customProperty = { 4 | propertyName: 'customProperty', 5 | propertySchema: { 6 | type: String, // property type 7 | label: 'customLabel', // key string used for internationalization 8 | optional: true, // make this property optional 9 | autoform: { 10 | editable: true, // make this property editable by users 11 | type: "bootstrap-datetimepicker", // assign a custom input type 12 | omit: false // set to true to omit field from form entirely 13 | } 14 | } 15 | } 16 | addToPostSchema.push(customProperty); -------------------------------------------------------------------------------- /packages/telescope-blank/lib/main.js: -------------------------------------------------------------------------------- 1 | // Global Function 2 | 3 | myFunction = function (a, b) { 4 | return a + b; 5 | } -------------------------------------------------------------------------------- /packages/telescope-blank/lib/routes.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function () { 2 | 3 | Router.route('/custom-path', { 4 | name: 'customRoute', 5 | template: getTemplate('customTemplate') 6 | }); 7 | 8 | }); -------------------------------------------------------------------------------- /packages/telescope-blank/lib/server/publications.js: -------------------------------------------------------------------------------- 1 | Meteor.publish('customPublication', function (limit) { 2 | return Posts.find({}, {limit: limit}); 3 | }); -------------------------------------------------------------------------------- /packages/telescope-blank/lib/settings.js: -------------------------------------------------------------------------------- 1 | // Custom Setting 2 | 3 | var customSetting = { 4 | propertyName: 'customSetting', 5 | propertySchema: { 6 | type: String, 7 | optional: true, 8 | autoform: { 9 | group: 'customGroup', // assign custom group (fieldset) in Settings form 10 | private: true // mark as private (not published to client) 11 | } 12 | } 13 | } 14 | addToSettingsSchema.push(customSetting); -------------------------------------------------------------------------------- /packages/telescope-blank/lib/templates.js: -------------------------------------------------------------------------------- 1 | // Override "postTitle" template 2 | 3 | templates["postTitle"] = "customPostTitle"; -------------------------------------------------------------------------------- /packages/telescope-blank/package-tap.i18n: -------------------------------------------------------------------------------- 1 | { 2 | "translation_function_name": "__", 3 | "helper_name": "_", 4 | "namespace": "project" 5 | } -------------------------------------------------------------------------------- /packages/telescope-daily/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/telescope-daily/i18n/de.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "daily": "Daily" 3 | } -------------------------------------------------------------------------------- /packages/telescope-daily/i18n/en.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "daily": "Daily", 3 | "day_by_day_view": "The most popular posts of each day.", 4 | "load_next_days": "Load Next Days" 5 | } -------------------------------------------------------------------------------- /packages/telescope-daily/i18n/es.i18n.json: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/packages/telescope-daily/i18n/es.i18n.json -------------------------------------------------------------------------------- /packages/telescope-daily/i18n/fr.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "daily": "Jour par jour" 3 | } -------------------------------------------------------------------------------- /packages/telescope-daily/i18n/it.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "daily": "Daily" 3 | } -------------------------------------------------------------------------------- /packages/telescope-daily/i18n/zh-CN.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "daily": "Daily" 3 | } -------------------------------------------------------------------------------- /packages/telescope-daily/lib/client/stylesheets/daily.scss: -------------------------------------------------------------------------------- 1 | .posts-day-heading{ 2 | font-size: 16px; 3 | color: rgba(0,0,0,0.5); 4 | margin: 0 0 10px 0; 5 | } 6 | .empty-day-notice{ 7 | padding: 15px; 8 | } 9 | .posts-day .post:last-child{ 10 | border-radius: 0 0 3px 3px; 11 | } 12 | .load-more-days-button{ 13 | display: block; 14 | background: none; 15 | width:100%; 16 | text-align:center; 17 | font-size:18px; 18 | padding: 0px; 19 | text-align: center; 20 | margin: 20px 0; 21 | } -------------------------------------------------------------------------------- /packages/telescope-daily/lib/client/templates/after_day.html: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /packages/telescope-daily/lib/client/templates/before_day.html: -------------------------------------------------------------------------------- 1 | 3 | -------------------------------------------------------------------------------- /packages/telescope-daily/lib/client/templates/posts_daily.html: -------------------------------------------------------------------------------- 1 | 14 | -------------------------------------------------------------------------------- /packages/telescope-daily/lib/client/templates/posts_daily.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function () { 2 | 3 | Template[getTemplate('postsDaily')].helpers({ 4 | days: function () { 5 | var daysArray = []; 6 | // var days = this.days; 7 | var days = Session.get('postsDays'); 8 | for (i = 0; i < days; i++) { 9 | daysArray.push({ 10 | date: moment().subtract(i, 'days').startOf('day').toDate(), 11 | index: i 12 | }); 13 | } 14 | return daysArray; 15 | }, 16 | before_day: function () { 17 | return getTemplate('beforeDay'); 18 | }, 19 | singleDay: function () { 20 | return getTemplate('singleDay'); 21 | }, 22 | context: function () { 23 | var context = this; 24 | context.showDateNav = false; 25 | return context; 26 | }, 27 | after_day: function () { 28 | return getTemplate('afterDay'); 29 | }, 30 | loadMoreDaysUrl: function () { 31 | var count = parseInt(Session.get('postsDays')) + daysPerPage; 32 | return '/daily/' + count; 33 | } 34 | }); 35 | 36 | }); 37 | -------------------------------------------------------------------------------- /packages/telescope-daily/lib/daily.js: -------------------------------------------------------------------------------- 1 | daysPerPage = 5; 2 | 3 | viewsMenu.push({ 4 | route: 'postsDaily', 5 | label: 'daily', 6 | description: 'day_by_day_view' 7 | }); -------------------------------------------------------------------------------- /packages/telescope-daily/lib/routes.js: -------------------------------------------------------------------------------- 1 | var coreSubscriptions = new SubsManager({ 2 | // cache recent 50 subscriptions 3 | cacheLimit: 50, 4 | // expire any subscription after 30 minutes 5 | expireIn: 30 6 | }); 7 | 8 | PostsDailyController = RouteController.extend({ 9 | 10 | template: function() { 11 | // use a function to make sure the template is evaluated *after* any template overrides 12 | return getTemplate('postsDaily'); 13 | }, 14 | 15 | subscriptions: function () { 16 | // this.days = this.params.days ? this.params.days : daysPerPage; 17 | // TODO: find a way to preload the first n posts of the first 5 days? 18 | }, 19 | 20 | data: function () { 21 | this.days = this.params.days ? this.params.days : daysPerPage; 22 | Session.set('postsDays', this.days); 23 | return { 24 | days: this.days 25 | }; 26 | }, 27 | 28 | getTitle: function () { 29 | return i18n.t('daily') + ' - ' + getSetting('title', "Telescope"); 30 | }, 31 | 32 | getDescription: function () { 33 | return i18n.t('day_by_day_view'); 34 | }, 35 | 36 | fastRender: true 37 | }); 38 | 39 | Meteor.startup(function () { 40 | 41 | Router.route('/daily/:days?', { 42 | name: 'postsDaily', 43 | controller: PostsDailyController 44 | }); 45 | 46 | }); -------------------------------------------------------------------------------- /packages/telescope-daily/package-tap.i18n: -------------------------------------------------------------------------------- 1 | { 2 | "translation_function_name": "__", 3 | "helper_name": "_", 4 | "namespace": "project" 5 | } -------------------------------------------------------------------------------- /packages/telescope-daily/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({summary: "Telescope daily view"}); 2 | 3 | Package.onUse(function (api) { 4 | 5 | api.use([ 6 | 'telescope-lib', 7 | 'telescope-base', 8 | 'iron:router', 9 | 'meteorhacks:fast-render', 10 | 'meteorhacks:subs-manager', 11 | 'tap:i18n', 12 | 'telescope-singleday', 13 | 'fourseven:scss' 14 | ], ['client', 'server']); 15 | 16 | api.use([ 17 | 'jquery', 18 | 'underscore', 19 | 'templating' 20 | ], 'client'); 21 | 22 | api.add_files([ 23 | 'package-tap.i18n', 24 | 'lib/daily.js', 25 | 'lib/routes.js', 26 | ], ['client', 'server']); 27 | 28 | api.add_files([ 29 | 'lib/client/templates/posts_daily.html', 30 | 'lib/client/templates/after_day.html', 31 | 'lib/client/templates/before_day.html', 32 | 'lib/client/templates/posts_daily.js', 33 | 'lib/client/stylesheets/daily.scss', 34 | ], ['client']); 35 | 36 | api.add_files([ 37 | "i18n/de.i18n.json", 38 | "i18n/en.i18n.json", 39 | "i18n/es.i18n.json", 40 | "i18n/fr.i18n.json", 41 | "i18n/it.i18n.json", 42 | "i18n/zh-CN.i18n.json", 43 | ], ["client", "server"]); 44 | 45 | api.export(['PostsDailyController']); 46 | }); -------------------------------------------------------------------------------- /packages/telescope-datetimepicker/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/telescope-datetimepicker/autoform-bs-datetimepicker.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/telescope-datetimepicker/fonts/glyphicons-halflings-regular.eot: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/packages/telescope-datetimepicker/fonts/glyphicons-halflings-regular.eot -------------------------------------------------------------------------------- /packages/telescope-datetimepicker/fonts/glyphicons-halflings-regular.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/packages/telescope-datetimepicker/fonts/glyphicons-halflings-regular.ttf -------------------------------------------------------------------------------- /packages/telescope-datetimepicker/fonts/glyphicons-halflings-regular.woff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/packages/telescope-datetimepicker/fonts/glyphicons-halflings-regular.woff -------------------------------------------------------------------------------- /packages/telescope-datetimepicker/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | name: 'telescope-datetimepicker', 3 | summary: 'Custom bootstrap-datetimepicker input type for AutoForm', 4 | version: '1.0.3', 5 | }); 6 | 7 | Package.onUse(function(api) { 8 | api.use('templating@1.0.0'); 9 | api.use('blaze@2.0.0'); 10 | api.use('aldeed:autoform'); 11 | api.use('fourseven:scss'); 12 | // api.use('jquery'); 13 | // api.use('tsega:bootstrap3-datetimepicker'); 14 | // api.use('chriswessels:glyphicons-halflings'); 15 | 16 | api.addFiles([ 17 | 'datetimepicker.scss', 18 | 'autoform-bs-datetimepicker.html', 19 | 'autoform-bs-datetimepicker.js', 20 | 'bootstrap-collapse-transitions.js', 21 | 'fonts/glyphicons-halflings-regular.eot', 22 | 'fonts/glyphicons-halflings-regular.svg', 23 | 'fonts/glyphicons-halflings-regular.ttf', 24 | 'fonts/glyphicons-halflings-regular.woff' 25 | ], 'client'); 26 | }); 27 | -------------------------------------------------------------------------------- /packages/telescope-email/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/telescope-email/.npm/package/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /packages/telescope-email/.npm/package/README: -------------------------------------------------------------------------------- 1 | This directory and the files immediately inside it are automatically generated 2 | when you change this package's NPM dependencies. Commit the files in this 3 | directory (npm-shrinkwrap.json, .gitignore, and this README) to source control 4 | so that others run the same versions of sub-dependencies. 5 | 6 | You should NOT check in the node_modules directory that Meteor automatically 7 | creates; if you are using git, the .gitignore file tells git to ignore it. 8 | -------------------------------------------------------------------------------- /packages/telescope-email/.npm/package/npm-shrinkwrap.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "html-to-text": { 4 | "version": "0.1.0", 5 | "dependencies": { 6 | "htmlparser": { 7 | "version": "1.7.7" 8 | }, 9 | "underscore": { 10 | "version": "1.7.0" 11 | }, 12 | "underscore.string": { 13 | "version": "2.3.3" 14 | }, 15 | "optimist": { 16 | "version": "0.6.1", 17 | "dependencies": { 18 | "wordwrap": { 19 | "version": "0.0.2" 20 | }, 21 | "minimist": { 22 | "version": "0.0.10" 23 | } 24 | } 25 | } 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/telescope-email/i18n/de.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "has_created_a_new_post": "has created a new post" 3 | } -------------------------------------------------------------------------------- /packages/telescope-email/i18n/en.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "has_created_a_new_post": "has created a new post" 3 | } -------------------------------------------------------------------------------- /packages/telescope-email/i18n/es.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "has_created_a_new_post": "has created a new post" 3 | } -------------------------------------------------------------------------------- /packages/telescope-email/i18n/fr.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "has_created_a_new_post": "a créé un nouveau post" 3 | } -------------------------------------------------------------------------------- /packages/telescope-email/i18n/it.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "has_created_a_new_post": "has created a new post" 3 | } -------------------------------------------------------------------------------- /packages/telescope-email/i18n/zh-CN.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "has_created_a_new_post": "has created a new post" 3 | } -------------------------------------------------------------------------------- /packages/telescope-email/lib/server/routes.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function () { 2 | 3 | // New user email 4 | 5 | Router.route('/email/new-user/:id?', { 6 | name: 'newUser', 7 | where: 'server', 8 | action: function() { 9 | var user = Meteor.users.findOne(this.params.id); 10 | var emailProperties = { 11 | profileUrl: getProfileUrl(user), 12 | username: getUserName(user) 13 | }; 14 | html = getEmailTemplate('emailNewUser')(emailProperties); 15 | this.response.write(buildEmailTemplate(html)); 16 | this.response.end(); 17 | } 18 | }); 19 | 20 | // New post email 21 | 22 | Router.route('/email/new-post/:id?', { 23 | name: 'newPost', 24 | where: 'server', 25 | action: function() { 26 | var post = Posts.findOne(this.params.id); 27 | if (!!post) { 28 | html = getEmailTemplate('emailNewPost')(getPostProperties(post)); 29 | } else { 30 | html = "

No post found.

" 31 | } 32 | this.response.write(buildEmailTemplate(html)); 33 | this.response.end(); 34 | } 35 | }); 36 | 37 | 38 | }); -------------------------------------------------------------------------------- /packages/telescope-email/lib/server/templates/emailAccountApproved.handlebars: -------------------------------------------------------------------------------- 1 | {{username}}, welcome to {{siteTitle}}!

2 | 3 | You've just been invited. Start posting.

-------------------------------------------------------------------------------- /packages/telescope-email/lib/server/templates/emailInvite.handlebars: -------------------------------------------------------------------------------- 1 | 2 | {{invitedBy}} 3 | invited you to join {{communityName}} 4 |

5 | 6 | {{#if newUser}} 7 | Join {{communityName}} 8 | {{else}} 9 | Sign in to {{communityName}} 10 | {{/if}} 11 |

12 | -------------------------------------------------------------------------------- /packages/telescope-email/lib/server/templates/emailNewComment.handlebars: -------------------------------------------------------------------------------- 1 | 2 | {{comment.author}} 3 | left a new comment on 4 | {{post.title}}: 5 | 6 |

7 | 8 |
9 | {{{body}}} 10 |
11 |
12 | 13 | Discuss

-------------------------------------------------------------------------------- /packages/telescope-email/lib/server/templates/emailNewPendingPost.handlebars: -------------------------------------------------------------------------------- 1 | 2 | {{postAuthorName}} 3 | has a new post pending approval: 4 | {{#if url}} 5 | {{postTitle}}} 6 | {{else}} 7 | {{postTitle}}} 8 | {{/if}} 9 |

10 | 11 | {{#if htmlBody}} 12 |
13 | {{{htmlBody}}} 14 |
15 |
16 | {{/if}} 17 | 18 | Go to post

19 | -------------------------------------------------------------------------------- /packages/telescope-email/lib/server/templates/emailNewPost.handlebars: -------------------------------------------------------------------------------- 1 | 2 | {{postAuthorName}} 3 | has created a new post: 4 | {{#if url}} 5 | {{postTitle}}} 6 | {{else}} 7 | {{postTitle}}} 8 | {{/if}} 9 |

10 | 11 | {{#if htmlBody}} 12 |
13 | {{{htmlBody}}} 14 |
15 |
16 | {{/if}} 17 | 18 | Discuss

19 | -------------------------------------------------------------------------------- /packages/telescope-email/lib/server/templates/emailNewReply.handlebars: -------------------------------------------------------------------------------- 1 | {{comment.author}} 2 | has replied to your comment on 3 | {{post.title}}: 4 | 5 |

6 | 7 |
8 | {{{body}}} 9 |
10 |
11 | 12 | Discuss

-------------------------------------------------------------------------------- /packages/telescope-email/lib/server/templates/emailNewUser.handlebars: -------------------------------------------------------------------------------- 1 | A new user account has been created: {{username}}

-------------------------------------------------------------------------------- /packages/telescope-email/lib/server/templates/emailPostApproved.handlebars: -------------------------------------------------------------------------------- 1 | 2 | Congratulations, your post has been approved: 3 | 4 |

5 | {{postTitle}}} 6 |

-------------------------------------------------------------------------------- /packages/telescope-email/lib/server/templates/emailTest.handlebars: -------------------------------------------------------------------------------- 1 | This is just a test

2 | 3 | Sent at {{date}}.

-------------------------------------------------------------------------------- /packages/telescope-email/package-tap.i18n: -------------------------------------------------------------------------------- 1 | { 2 | "translation_function_name": "__", 3 | "helper_name": "_" 4 | } -------------------------------------------------------------------------------- /packages/telescope-embedly/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/telescope-embedly/History.md: -------------------------------------------------------------------------------- 1 | ### v0.2.9 2 | 3 | - Update to Meteor 0.9.0. 4 | 5 | ### v0.2.8 6 | 7 | - Don't display image if it cannot be found. -------------------------------------------------------------------------------- /packages/telescope-embedly/README.md: -------------------------------------------------------------------------------- 1 | The Telescope [Embedly](http://embed.ly) module. 2 | 3 | More details in [this blog post](http://telesc.pe/blog/extending-telescope-with-embedly-thumbnails/). 4 | 5 | ### Install 6 | 7 | 1. `mrt add telescope-module-embedly`. 8 | 2. Go to the Telescope settings page and add your Embedly API key. 9 | 10 | ### Extra Features 11 | 12 | When linking to videos, the thumbnail becomes clickable and opens the video in a lightbox. -------------------------------------------------------------------------------- /packages/telescope-embedly/i18n/en.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "thumbnail": "Thumbnail", 3 | "thumbnailUrl": "Thumbnail", 4 | "regenerate_thumbnail": "Regenerate Thumbnail", 5 | "clear_thumbnail": "Clear Thumbnail", 6 | "please_fill_in_embedly_key": "Please fill in your Embedly API key to enable thumbnails." 7 | } -------------------------------------------------------------------------------- /packages/telescope-embedly/i18n/fr.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "thumbnail": "Aperçu", 3 | "thumbnailUrl": "Aperçu", 4 | "regenerate_thumbnail": "Regenerer l'aperçu", 5 | "clear_thumbnail": "Effacer l'aperçu", 6 | "please_fill_in_embedly_key": "Veuillez fournir une clé API Embedly pour activer les aperçus." 7 | } -------------------------------------------------------------------------------- /packages/telescope-embedly/lib/client/autoform-postthumbnail.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/telescope-embedly/lib/client/post_thumbnail.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/telescope-embedly/lib/client/post_thumbnail.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('postThumbnail')].helpers({ 2 | postLink: function () { 3 | return !!this.url ? getOutgoingUrl(this.url) : "/posts/"+this._id; 4 | }, 5 | playVideoClass: function () { 6 | return !!this.media ? 'post-thumbnail-has-video': ''; 7 | }, 8 | videoTemplate: function () { 9 | return getTemplate('postVideo'); 10 | } 11 | }); 12 | 13 | Template[getTemplate('postThumbnail')].events({ 14 | 'click .post-thumbnail-has-video': function (e) { 15 | e.preventDefault(); 16 | $('body').addClass('showing-lightbox'); 17 | $(e.target).parents('.post').find('.post-video-lightbox').fadeIn('fast'); 18 | } 19 | }) -------------------------------------------------------------------------------- /packages/telescope-embedly/lib/client/post_video.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/telescope-embedly/lib/client/post_video.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('postVideo')].events({ 2 | 'click .post-video-lightbox-hide, click .post-video-lightbox': function (e) { 3 | e.preventDefault(); 4 | $(e.target).parents('.post').find('.post-video-lightbox').fadeOut('fast'); 5 | $('body').removeClass('showing-lightbox'); 6 | } 7 | }) -------------------------------------------------------------------------------- /packages/telescope-embedly/package-tap.i18n: -------------------------------------------------------------------------------- 1 | { 2 | "translation_function_name": "__", 3 | "helper_name": "_", 4 | "namespace": "project" 5 | } -------------------------------------------------------------------------------- /packages/telescope-embedly/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | summary: "Telescope Embedly module package", 3 | version: '0.2.9', 4 | name: "telescope-embedly", 5 | git: 'https://github.com/TelescopeJS/Telescope-Module-Embedly.git' 6 | }); 7 | 8 | Package.onUse( function(api) { 9 | 10 | api.versionsFrom("METEOR@0.9.0"); 11 | 12 | api.use([ 13 | 'telescope-lib', 14 | 'telescope-base', 15 | 'aldeed:autoform', 16 | 'tap:i18n', 17 | 'fourseven:scss', 18 | 'templating', 19 | 'http' 20 | ]); 21 | 22 | api.add_files([ 23 | 'package-tap.i18n', 24 | 'lib/embedly.js' 25 | ], ['client', 'server']); 26 | 27 | api.add_files([ 28 | 'lib/server/get_embedly_data.js' 29 | ], ['server']); 30 | 31 | api.add_files([ 32 | 'lib/client/autoform-postthumbnail.html', 33 | 'lib/client/autoform-postthumbnail.js', 34 | 'lib/client/post_thumbnail.html', 35 | 'lib/client/post_thumbnail.js', 36 | 'lib/client/post_thumbnail.scss', 37 | 'lib/client/post_video.html', 38 | 'lib/client/post_video.js' 39 | ], ['client']); 40 | 41 | api.add_files([ 42 | "i18n/en.i18n.json", 43 | "i18n/fr.i18n.json" 44 | ], ["client", "server"]); 45 | }); -------------------------------------------------------------------------------- /packages/telescope-getting-started/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/telescope-getting-started/content/customizing_telescope.md: -------------------------------------------------------------------------------- 1 | ### Changing Colors 2 | 3 | Telescope is fairly flexible out of the box. You can tweak colors for the header and buttons in the [Settings](/settings) panel. 4 | 5 | ### Enabling Thumbnails 6 | 7 | If you'd like, you can also enable post thumbnails. You'll need to get an [Embedly](http://embed.ly) API key first, and then simply add it in the Settings screen. 8 | 9 | ### Enabling The Newsletter 10 | 11 | Telescope can also automatically generate and send a newsletter of the best posts of the day or week. All you need to do is provide your MailChimp API key and list ID in the Settings screen, choose the sending frequency, and then enable the newsletter. 12 | 13 | If you want to learn more, be sure to check out the [Email](http://www.telesc.pe/docs/packages/email/) section of the documentation as well. 14 | 15 | ### Customizing Your Templates 16 | 17 | Telescope also makes it possible to completely override any part of your app with your own custom templates. 18 | 19 | As usual, you'll learn more about this in [the documentation](http://www.telesc.pe/docs/customizing/theming-telescope/). -------------------------------------------------------------------------------- /packages/telescope-getting-started/content/deploying_telescope.md: -------------------------------------------------------------------------------- 1 | ### Quick Deploy 2 | 3 | Once you've played around with Telescope, you might want to deploy your app for the whole world to see. 4 | 5 | You can do so easily using Meteor's own free hosting service. Just open a terminal window, go to your Telescope app's directory, and type: 6 | 7 | ``` 8 | meteor deploy my-app 9 | ``` 10 | 11 | Where `my-app` is a unique name you'll pick for your Telescope app. It will then be deployed to `http://my-app.meteor.com`. 12 | 13 | You might need to create a Meteor account first. Just follow the instructions! 14 | 15 | Note that deploying does *not* copy over your database, which contains your posts and settings. So you'll need to configure them separately on your remote Telescope instance. 16 | 17 | ### Deploying For Production 18 | 19 | Hosting on `*.meteor.com` is fine for small apps and prototypes, but if you want to deploy your app in production you'll need something better. 20 | 21 | Check out [the Telescope documentation](http://www.telesc.pe/docs/getting-started/deploying/) to learn more about this topic. -------------------------------------------------------------------------------- /packages/telescope-getting-started/content/getting_help.md: -------------------------------------------------------------------------------- 1 | ### Stack Overflow 2 | 3 | The best place to ask for help with specific Telescope questions is [Stack Overflow](http://stackoverflow.com/questions/tagged/telescope). Just make sure you use the `telescope` tag! 4 | 5 | ### Telescope Meta 6 | 7 | If you don't have a question, but instead want to discuss a specific aspect of Telescope (or show the world your new Telescope site!), feel free to open a topic on [Telescope Meta](http://meta.telesc.pe). 8 | 9 | ### GitHub Issues 10 | 11 | Finally, if you've found a bug in Telescope, then you should [leave an issue on GitHub](https://github.com/TelescopeJS/Telescope/issues). -------------------------------------------------------------------------------- /packages/telescope-getting-started/content/images/stackoverflow.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/packages/telescope-getting-started/content/images/stackoverflow.png -------------------------------------------------------------------------------- /packages/telescope-getting-started/content/images/telescope.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/packages/telescope-getting-started/content/images/telescope.png -------------------------------------------------------------------------------- /packages/telescope-getting-started/content/read_this_first.md: -------------------------------------------------------------------------------- 1 | ### Welcome to Telescope! 2 | 3 | If you're reading this, it means you've successfully got Telescope to run. 4 | 5 | To make your first run a bit easier, we've taken the liberty of preloading your brand new app with a few posts that will walk you through your first steps with Telescope. 6 | 7 | ### 1. Creating An Account 8 | 9 | The first thing you'll need to do is create your account. Since this will be the first ever account created in this app, it will automatically be assigned admin rights, and you'll then be able to access Telescope's settings panel. 10 | 11 | Click the “Sign Up” link in the top menu and come back here once you're done! 12 | 13 | ### 2. Configuring Settings 14 | 15 | The next step is configuring a few basic settings, such as your site's title, logo, or language. Don't worry, you can change all of these at any time! 16 | 17 | To do so, go to the “Admin” menu and click on “Settings”. 18 | 19 | ### 3. Start Posting! 20 | 21 | You're now all set to start using Telescope. Check out the other posts for more information, or just start posting! -------------------------------------------------------------------------------- /packages/telescope-getting-started/content/removing_getting_started_posts.md: -------------------------------------------------------------------------------- 1 | ### Removing Getting Started Posts 2 | 3 | If you're ready to insert your own content and want to delete these getting started posts, comments, and users, you can do so with a single command. 4 | 5 | Just make sure you're logged in, then open your [browser console](http://webmasters.stackexchange.com/questions/8525/how-to-open-the-javascript-console-in-different-browsers) and type: 6 | 7 | ```js 8 | Meteor.call('removeGettingStartedContent'); 9 | ``` 10 | 11 | See you on the other side! -------------------------------------------------------------------------------- /packages/telescope-getting-started/i18n/en.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "translation_key": "translation string" 3 | } -------------------------------------------------------------------------------- /packages/telescope-getting-started/lib/getting_started.js: -------------------------------------------------------------------------------- 1 | addToPostSchema.push( 2 | { 3 | propertyName: 'dummySlug', 4 | propertySchema: { 5 | type: String, 6 | optional: true, 7 | autoform: { 8 | omit: true 9 | } 10 | } 11 | } 12 | ); 13 | 14 | addToPostSchema.push( 15 | { 16 | propertyName: 'isDummy', 17 | propertySchema: { 18 | type: Boolean, 19 | optional: true, 20 | autoform: { 21 | omit: true 22 | } 23 | } 24 | } 25 | ); 26 | 27 | addToCommentsSchema.push( 28 | { 29 | propertyName: 'isDummy', 30 | propertySchema: { 31 | type: Boolean, 32 | optional: true, 33 | autoform: { 34 | omit: true 35 | } 36 | } 37 | } 38 | ); -------------------------------------------------------------------------------- /packages/telescope-getting-started/package-tap.i18n: -------------------------------------------------------------------------------- 1 | { 2 | "translation_function_name": "__", 3 | "helper_name": "_", 4 | "namespace": "project" 5 | } -------------------------------------------------------------------------------- /packages/telescope-i18n/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/telescope-i18n/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({summary: "Telescope i18n package"}); 2 | 3 | Package.onUse(function (api) { 4 | api.use(["tap:i18n"], ["client", "server"]); 5 | api.use(["session"], "client"); 6 | api.add_files(['i18n.js'], ['client', 'server']); 7 | api.export([ 8 | 'i18n', 9 | 'setLanguage' 10 | ]); 11 | }); 12 | -------------------------------------------------------------------------------- /packages/telescope-invites/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/telescope-invites/i18n/de.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "translation_key": "translation string" 3 | } -------------------------------------------------------------------------------- /packages/telescope-invites/i18n/en.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "translation_key": "translation string" 3 | } -------------------------------------------------------------------------------- /packages/telescope-invites/i18n/es.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "translation_key": "translation string" 3 | } -------------------------------------------------------------------------------- /packages/telescope-invites/i18n/fr.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "translation_key": "translation string" 3 | } -------------------------------------------------------------------------------- /packages/telescope-invites/i18n/it.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "translation_key": "translation string" 3 | } -------------------------------------------------------------------------------- /packages/telescope-invites/i18n/zh-CN.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "translation_key": "translation string" 3 | } -------------------------------------------------------------------------------- /packages/telescope-invites/lib/client/templates/user_invites.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/telescope-invites/lib/server/publications.js: -------------------------------------------------------------------------------- 1 | Meteor.publish('invites', function (userId) { 2 | var invites = Invites.find({invitingUserId: userId}) 3 | return (this.userId === userId || isAdmin(Meteor.user())) ? invites : [] 4 | }); -------------------------------------------------------------------------------- /packages/telescope-invites/package-tap.i18n: -------------------------------------------------------------------------------- 1 | { 2 | "translation_function_name": "__", 3 | "helper_name": "_", 4 | "namespace": "project" 5 | } -------------------------------------------------------------------------------- /packages/telescope-kadira/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/telescope-kadira/lib/kadira-settings.js: -------------------------------------------------------------------------------- 1 | var kadiraAppIdProperty = { 2 | propertyName: 'kadiraAppId', 3 | propertyGroup: 'kadira', 4 | propertySchema: { 5 | type: String, 6 | optional: true, 7 | autoform: { 8 | group: 'kadira' 9 | } 10 | } 11 | } 12 | addToSettingsSchema.push(kadiraAppIdProperty); 13 | 14 | var kadiraAppSecretProperty = { 15 | propertyName: 'kadiraAppSecret', 16 | propertyGroup: 'kadira', 17 | propertySchema: { 18 | type: String, 19 | optional: true, 20 | autoform: { 21 | group: 'kadira', 22 | private: true 23 | } 24 | } 25 | } 26 | addToSettingsSchema.push(kadiraAppSecretProperty); -------------------------------------------------------------------------------- /packages/telescope-kadira/lib/server/kadira.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function() { 2 | if(!!getSetting('kadiraAppId') && !!getSetting('kadiraAppSecret')){ 3 | Kadira.connect(getSetting('kadiraAppId'), getSetting('kadiraAppSecret')); 4 | } 5 | }); -------------------------------------------------------------------------------- /packages/telescope-kadira/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | summary: "Telescope Kadira package", 3 | version: '0.1.0', 4 | name: "telescope-kadira" 5 | }); 6 | 7 | Package.onUse(function (api) { 8 | 9 | api.use([ 10 | 'telescope-lib', 11 | 'telescope-base' 12 | ], ['client', 'server']); 13 | 14 | api.use([ 15 | 'meteorhacks:kadira@2.14.0' 16 | ], ['server']); 17 | 18 | api.add_files([ 19 | 'lib/kadira-settings.js' 20 | ], ['client', 'server']); 21 | 22 | api.add_files([ 23 | 'lib/server/kadira.js' 24 | ], ['server']); 25 | 26 | }); -------------------------------------------------------------------------------- /packages/telescope-lib/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/telescope-lib/lib/autolink.js: -------------------------------------------------------------------------------- 1 | //https://github.com/bryanwoods/autolink-js 2 | (function(){var a,b=[].slice;a=function(){var j,i,d,f,e,c,g,h;c=1<=arguments.length?b.call(arguments,0):[];g=/(^|\s)(\b(https?):\/\/[\-A-Z0-9+&@#\/%?=~_|!:,.;]*[\-A-Z0-9+&@#\/%=~_|]\b)/ig;if(c.length>0){e=c[0];i=e.callback;if((i!=null)&&typeof i==="function"){j=i;delete e.callback;}f="";for(d in e){h=e[d];f+=" "+d+"='"+h+"'";}return this.replace(g,function(l,o,k){var n,m;m=j&&j(k);n=m||(""+k+"");return""+o+n;});}else{return this.replace(g,"$1$2");}};String.prototype.autoLink=a;}).call(this); 3 | -------------------------------------------------------------------------------- /packages/telescope-lib/lib/client/jquery.exists.js: -------------------------------------------------------------------------------- 1 | $.fn.exists = function () { 2 | return this.length !== 0; 3 | } -------------------------------------------------------------------------------- /packages/telescope-lib/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | summary: "Telescope library package", 3 | version: '0.2.9', 4 | name: "telescope-lib" 5 | }); 6 | 7 | Package.onUse(function (api) { 8 | 9 | api.use([ 10 | 'underscore' 11 | ], ['client', 'server']); 12 | 13 | api.use([ 14 | 'jquery' 15 | ], 'client'); 16 | 17 | api.add_files([ 18 | 'lib/lib.js', 19 | 'lib/deep.js', 20 | 'lib/deep_extend.js', 21 | 'lib/autolink.js', 22 | 'lib/permissions.js' 23 | ], ['client', 'server']); 24 | 25 | api.add_files(['lib/client/jquery.exists.js'], ['client']); 26 | 27 | api.export([ 28 | 'deepExtend', 29 | 'camelToDash', 30 | 'dashToCamel', 31 | 'camelCaseify', 32 | 'getSetting', 33 | 'getThemeSetting', 34 | 'getSiteUrl', 35 | 'trimWords', 36 | 'can', 37 | '_', 38 | 'capitalise' 39 | ]); 40 | }); -------------------------------------------------------------------------------- /packages/telescope-lib/versions.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": [ 3 | [ 4 | "jquery", 5 | "1.0.1" 6 | ], 7 | [ 8 | "meteor", 9 | "1.1.3" 10 | ], 11 | [ 12 | "underscore", 13 | "1.0.1" 14 | ] 15 | ], 16 | "pluginDependencies": [], 17 | "toolVersion": "meteor-tool@1.0.36", 18 | "format": "1.0" 19 | } -------------------------------------------------------------------------------- /packages/telescope-module-share/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/telescope-module-share/lib/client/post_share.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/telescope-module-share/lib/client/post_share.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function () { 2 | Template[getTemplate('postShare')].helpers({ 3 | sourceLink: function(){ 4 | return !!this.url ? this.url : getSiteUrl() + "posts/"+this._id; 5 | }, 6 | viaTwitter: function () { 7 | return !!getSetting('twitterAccount') ? 'via='+getSetting('twitterAccount') : ''; 8 | } 9 | }); 10 | 11 | Template[getTemplate('postShare')].events({ 12 | 'click .share-link': function(e){ 13 | var $this = $(e.target).parents('.post-share').find('.share-link'); 14 | var $share = $this.parents('.post-share').find('.share-options'); 15 | e.preventDefault(); 16 | $('.share-link').not($this).removeClass("active"); 17 | $(".share-options").not($share).addClass("hidden"); 18 | $this.toggleClass("active"); 19 | $share.toggleClass("hidden"); 20 | } 21 | }); 22 | }); -------------------------------------------------------------------------------- /packages/telescope-module-share/lib/share.js: -------------------------------------------------------------------------------- 1 | postModules.push({ 2 | template: 'postShare', 3 | order: 25 4 | }); -------------------------------------------------------------------------------- /packages/telescope-module-share/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({summary: "Telescope share module package"}); 2 | 3 | Package.onUse(function (api) { 4 | 5 | api.use(['telescope-lib', 'telescope-base', 'fourseven:scss'], ['client', 'server']); 6 | 7 | api.use([ 8 | 'jquery', 9 | 'underscore', 10 | 'templating' 11 | ], 'client'); 12 | 13 | api.add_files(['lib/share.js'], ['client', 'server']); 14 | 15 | api.add_files(['lib/client/post_share.html', 'lib/client/post_share.js', 'lib/client/post_share.scss'], ['client']); 16 | 17 | // api.export(); 18 | }); -------------------------------------------------------------------------------- /packages/telescope-newsletter/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/telescope-newsletter/.npm/package/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /packages/telescope-newsletter/.npm/package/README: -------------------------------------------------------------------------------- 1 | This directory and the files immediately inside it are automatically generated 2 | when you change this package's NPM dependencies. Commit the files in this 3 | directory (npm-shrinkwrap.json, .gitignore, and this README) to source control 4 | so that others run the same versions of sub-dependencies. 5 | 6 | You should NOT check in the node_modules directory that Meteor automatically 7 | creates; if you are using git, the .gitignore file tells git to ignore it. 8 | -------------------------------------------------------------------------------- /packages/telescope-newsletter/.npm/package/npm-shrinkwrap.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "html-to-text": { 4 | "version": "0.1.0", 5 | "dependencies": { 6 | "htmlparser": { 7 | "version": "1.7.7" 8 | }, 9 | "underscore": { 10 | "version": "1.7.0" 11 | }, 12 | "underscore.string": { 13 | "version": "2.3.3" 14 | }, 15 | "optimist": { 16 | "version": "0.6.1", 17 | "dependencies": { 18 | "wordwrap": { 19 | "version": "0.0.2" 20 | }, 21 | "minimist": { 22 | "version": "0.0.10" 23 | } 24 | } 25 | } 26 | } 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /packages/telescope-newsletter/History.md: -------------------------------------------------------------------------------- 1 | ## v0.1.6 2 | 3 | - Return error message or campaign subject for cron job. 4 | - Change Newsletter Frequency option to a `select` input. 5 | 6 | ## v0.1.5 7 | 8 | - Added option to show/hide newsletter sign-up banner -------------------------------------------------------------------------------- /packages/telescope-newsletter/i18n/de.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "receive_the_best_of": "Receive the best of", 3 | "right_in_your_inbox": "right in your inbox.", 4 | "get_newsletter": "Get Newsletter", 5 | "thanks_for_subscribing": "Thanks for subscribing!" 6 | } -------------------------------------------------------------------------------- /packages/telescope-newsletter/i18n/en.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "receive_the_best_of": "Receive the best of", 3 | "right_in_your_inbox": "right in your inbox.", 4 | "get_newsletter": "Get Newsletter", 5 | "thanks_for_subscribing": "Thanks for subscribing!", 6 | "newsletter": "newsletter", 7 | "showBanner": "Show Banner", 8 | "mailChimpAPIKey": "MailChimp API Key", 9 | "mailChimpListId": "MailChimp List ID", 10 | "postsPerNewsletter": "Posts per Newsletter", 11 | "newsletterFrequency": "Newsletter Frequency", 12 | "newsletterTime": "Newsletter Time", 13 | "enableNewsletter": "Enable Newsletter", 14 | "autoSubscribe": "Auto Subscribe" 15 | } -------------------------------------------------------------------------------- /packages/telescope-newsletter/i18n/es.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "receive_the_best_of": "Receive the best of", 3 | "right_in_your_inbox": "right in your inbox.", 4 | "get_newsletter": "Get Newsletter", 5 | "thanks_for_subscribing": "Thanks for subscribing!" 6 | } -------------------------------------------------------------------------------- /packages/telescope-newsletter/i18n/fr.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "receive_the_best_of": "Receive the best of", 3 | "right_in_your_inbox": "right in your inbox.", 4 | "get_newsletter": "Get Newsletter", 5 | "thanks_for_subscribing": "Thanks for subscribing!", 6 | "newsletter": "newsletter", 7 | "showBanner": "Afficher la Bannière", 8 | "mailChimpAPIKey": "Clé API MailChimp", 9 | "mailChimpListId": "ID Liste MailChimp", 10 | "postsPerNewsletter": "Posts par Newsletter", 11 | "newsletterFrequency": "Fréquence de la Newsletter" 12 | } -------------------------------------------------------------------------------- /packages/telescope-newsletter/i18n/it.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "receive_the_best_of": "Receive the best of", 3 | "right_in_your_inbox": "right in your inbox.", 4 | "get_newsletter": "Get Newsletter", 5 | "thanks_for_subscribing": "Thanks for subscribing!" 6 | } -------------------------------------------------------------------------------- /packages/telescope-newsletter/i18n/zh-CN.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "receive_the_best_of": "Receive the best of", 3 | "right_in_your_inbox": "right in your inbox.", 4 | "get_newsletter": "Get Newsletter", 5 | "thanks_for_subscribing": "Thanks for subscribing!" 6 | } -------------------------------------------------------------------------------- /packages/telescope-newsletter/lib/client/templates/newsletter_banner.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/telescope-newsletter/lib/server/routes.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function () { 2 | 3 | Router.route('/email/campaign', { 4 | name: 'campaign', 5 | where: 'server', 6 | action: function() { 7 | var campaign = buildCampaign(getCampaignPosts(getSetting('postsPerNewsletter', 5))); 8 | var campaignSubject = '
Subject: '+campaign.subject+' (note: contents might change)
'; 9 | var campaignSchedule = '
Scheduled for: '+ Meteor.call('getNextJob') +'
'; 10 | 11 | this.response.write(campaignSubject+campaignSchedule+campaign.html); 12 | this.response.end(); 13 | } 14 | }); 15 | 16 | Router.route('/email/digest-confirmation', { 17 | name: 'digestConfirmation', 18 | where: 'server', 19 | action: function() { 20 | var confirmationHtml = getEmailTemplate('emailDigestConfirmation')({ 21 | time: 'January 1st, 1901', 22 | newsletterLink: 'http://example.com', 23 | subject: 'Lorem ipsum dolor sit amet' 24 | }); 25 | this.response.write(buildEmailTemplate(confirmationHtml)); 26 | this.response.end(); 27 | } 28 | }); 29 | 30 | }); -------------------------------------------------------------------------------- /packages/telescope-newsletter/lib/server/templates/emailDigest.handlebars: -------------------------------------------------------------------------------- 1 | 40 | 41 | Recently on {{siteName}} 42 | – {{date}} 43 |

44 | 45 |
46 | {{{content}}} 47 |
48 |
-------------------------------------------------------------------------------- /packages/telescope-newsletter/lib/server/templates/emailDigestConfirmation.handlebars: -------------------------------------------------------------------------------- 1 | Newsletter scheduled for {{time}}

2 | 3 | {{subject}}

-------------------------------------------------------------------------------- /packages/telescope-newsletter/lib/server/templates/emailPostItem.handlebars: -------------------------------------------------------------------------------- 1 |
2 |
3 | 4 | 5 | {{#if thumbnailUrl}} 6 |   7 | {{/if}} 8 | 9 | {{title}} 10 | 11 | 12 |
13 | {{#if domain}} 14 | {{domain}} 15 | | 16 | {{/if}} 17 | 18 | 19 | | 20 | {{commentCount}} Comments 21 |
22 | 23 | 24 | {{#if body}} 25 |
26 | {{{htmlBody}}} 27 | Read more 28 |
29 | {{/if}} 30 | 31 | 32 |
33 |
34 | 35 | -------------------------------------------------------------------------------- /packages/telescope-newsletter/package-tap.i18n: -------------------------------------------------------------------------------- 1 | { 2 | "translation_function_name": "__", 3 | "helper_name": "_", 4 | "namespace": "project" 5 | } -------------------------------------------------------------------------------- /packages/telescope-notifications/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/telescope-notifications/i18n/de.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "left_a_new_comment_on": "left a new comment on", 3 | "has_replied_to_your_comment_on": "has replied to your comment on", 4 | "mark_as_read": "Mark as read", 5 | "no_notifications": "No notifications", 6 | "you_have_been_unsubscribed_from_all_notifications": "You have been unsubscribed from all notifications.", 7 | "user_not_found": "User not found", 8 | "1_notification": "1 notification", 9 | "notifications": "notifications" 10 | } -------------------------------------------------------------------------------- /packages/telescope-notifications/i18n/en.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "left_a_new_comment_on": "left a new comment on", 3 | "has_replied_to_your_comment_on": "has replied to your comment on", 4 | "mark_as_read": "Mark as read", 5 | "no_notifications": "No notifications", 6 | "you_have_been_unsubscribed_from_all_notifications": "You have been unsubscribed from all notifications.", 7 | "user_not_found": "User not found", 8 | "1_notification": "1 notification", 9 | "notifications": "notifications", 10 | "notifications_fieldset": "Notifications", 11 | "emailNotifications": "Email Notifications", 12 | "your_post": "Your post", 13 | "has_been_approved": "has been approved" 14 | } 15 | -------------------------------------------------------------------------------- /packages/telescope-notifications/i18n/es.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "left_a_new_comment_on": "left a new comment on", 3 | "has_replied_to_your_comment_on": "has replied to your comment on", 4 | "mark_as_read": "Mark as read", 5 | "no_notifications": "No notifications", 6 | "you_have_been_unsubscribed_from_all_notifications": "You have been unsubscribed from all notifications.", 7 | "user_not_found": "User not found", 8 | "1_notification": "1 notification", 9 | "notifications": "notifications" 10 | } -------------------------------------------------------------------------------- /packages/telescope-notifications/i18n/fr.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "left_a_new_comment_on": "a laissé un nouveau commentaire sur", 3 | "has_replied_to_your_comment_on": "a répondu à", 4 | "mark_as_read": "Marquer comme lu", 5 | "no_notifications": "Aucune notification", 6 | "you_have_been_unsubscribed_from_all_notifications": "Vous avez été désabonné de toutes les notifications.", 7 | "user_not_found": "Utilisateur non trouvé", 8 | "1_notification": "1 notification", 9 | "notifications": "notifications", 10 | "emailNotifications": "Notifications par Email", 11 | "your_post": "Votre post", 12 | "has_been_approved": "a été approuvé" 13 | } -------------------------------------------------------------------------------- /packages/telescope-notifications/i18n/it.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "left_a_new_comment_on": "left a new comment on", 3 | "has_replied_to_your_comment_on": "has replied to your comment on", 4 | "mark_as_read": "Mark as read", 5 | "no_notifications": "No notifications", 6 | "you_have_been_unsubscribed_from_all_notifications": "You have been unsubscribed from all notifications.", 7 | "user_not_found": "User not found", 8 | "1_notification": "1 notification", 9 | "notifications": "notifications" 10 | } -------------------------------------------------------------------------------- /packages/telescope-notifications/i18n/zh-CN.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "left_a_new_comment_on": "left a new comment on", 3 | "has_replied_to_your_comment_on": "has replied to your comment on", 4 | "mark_as_read": "Mark as read", 5 | "no_notifications": "No notifications", 6 | "you_have_been_unsubscribed_from_all_notifications": "You have been unsubscribed from all notifications.", 7 | "user_not_found": "User not found", 8 | "1_notification": "1 notification", 9 | "notifications": "notifications" 10 | } -------------------------------------------------------------------------------- /packages/telescope-notifications/lib/client/templates/notification_item.html: -------------------------------------------------------------------------------- 1 | 9 | -------------------------------------------------------------------------------- /packages/telescope-notifications/lib/client/templates/notification_item.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('notificationItem')].helpers({ 2 | properties: function(){ 3 | return this.data; 4 | }, 5 | notificationHTML: function(){ 6 | return this.message(); 7 | } 8 | }); 9 | 10 | Template[getTemplate('notificationItem')].events({ 11 | 'click .action-link': function(event, instance){ 12 | var notificationId=instance.data._id; 13 | Herald.collection.update( 14 | {_id: notificationId}, 15 | { 16 | $set:{ 17 | read: true 18 | } 19 | }, 20 | function(error, result){ 21 | if(error){ 22 | console.log(error); 23 | } 24 | } 25 | ); 26 | } 27 | }); 28 | -------------------------------------------------------------------------------- /packages/telescope-notifications/lib/client/templates/notification_new_comment.html: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /packages/telescope-notifications/lib/client/templates/notification_new_reply.html: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /packages/telescope-notifications/lib/client/templates/notification_post_approved.html: -------------------------------------------------------------------------------- 1 | 8 | -------------------------------------------------------------------------------- /packages/telescope-notifications/lib/client/templates/notifications_menu.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/telescope-notifications/lib/client/templates/unsubscribe.html: -------------------------------------------------------------------------------- 1 | 6 | -------------------------------------------------------------------------------- /packages/telescope-notifications/lib/client/templates/unsubscribe.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('unsubscribe')].created = function(){ 2 | var hash = this.data.hash; 3 | Meteor.call('unsubscribeUser', hash, function(error, result){ 4 | if(result){ 5 | Session.set('unsubscribedMessage', __('you_have_been_unsubscribed_from_all_notifications')); 6 | }else{ 7 | Session.set('unsubscribedMessage', __('user_not_found')); 8 | } 9 | }); 10 | trackEvent('notificationsUnsubcribe', {hash: hash}); 11 | }; 12 | 13 | Template[getTemplate('unsubscribe')].helpers({ 14 | unsubscribed : function(){ 15 | // we have to use a session variable because the string we want to display 16 | // depends on the return value of an asynchronous callback (unsubscribeUser) 17 | return Session.get('unsubscribedMessage'); 18 | } 19 | }); -------------------------------------------------------------------------------- /packages/telescope-notifications/lib/server/routes.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function () { 2 | 3 | // Notification email 4 | 5 | Router.route('/email/notification/:id?', { 6 | name: 'notification', 7 | where: 'server', 8 | action: function() { 9 | var notification = Herald.collection.findOne(this.params.id); 10 | var notificationContents = buildEmailNotification(notification); 11 | this.response.write(notificationContents.html); 12 | this.response.end(); 13 | } 14 | }); 15 | 16 | }); -------------------------------------------------------------------------------- /packages/telescope-notifications/package-tap.i18n: -------------------------------------------------------------------------------- 1 | { 2 | "translation_function_name": "__", 3 | "helper_name": "_", 4 | "namespace": "project" 5 | } -------------------------------------------------------------------------------- /packages/telescope-post-by-feed/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/telescope-post-by-feed/.npm/package/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /packages/telescope-post-by-feed/.npm/package/README: -------------------------------------------------------------------------------- 1 | This directory and the files immediately inside it are automatically generated 2 | when you change this package's NPM dependencies. Commit the files in this 3 | directory (npm-shrinkwrap.json, .gitignore, and this README) to source control 4 | so that others run the same versions of sub-dependencies. 5 | 6 | You should NOT check in the node_modules directory that Meteor automatically 7 | creates; if you are using git, the .gitignore file tells git to ignore it. 8 | -------------------------------------------------------------------------------- /packages/telescope-post-by-feed/.npm/package/npm-shrinkwrap.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "he": { 4 | "version": "0.5.0" 5 | }, 6 | "htmlparser2": { 7 | "version": "3.8.2", 8 | "dependencies": { 9 | "domhandler": { 10 | "version": "2.3.0" 11 | }, 12 | "domutils": { 13 | "version": "1.5.0" 14 | }, 15 | "domelementtype": { 16 | "version": "1.1.3" 17 | }, 18 | "readable-stream": { 19 | "version": "1.1.13", 20 | "dependencies": { 21 | "core-util-is": { 22 | "version": "1.0.1" 23 | }, 24 | "isarray": { 25 | "version": "0.0.1" 26 | }, 27 | "string_decoder": { 28 | "version": "0.10.31" 29 | }, 30 | "inherits": { 31 | "version": "2.0.1" 32 | } 33 | } 34 | }, 35 | "entities": { 36 | "version": "1.0.0" 37 | } 38 | } 39 | }, 40 | "to-markdown": { 41 | "version": "0.0.2" 42 | } 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /packages/telescope-post-by-feed/i18n/en.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "feed_already_exists": "A feed with the same URL already exists.", 3 | "you_need_to_login_and_be_an_admin_to_add_a_new_feed": "You need to log in and be an admin to add a new feed.", 4 | "import_new_posts_from_feeds": "Import new posts from feeds." 5 | } 6 | -------------------------------------------------------------------------------- /packages/telescope-post-by-feed/lib/client/routes.js: -------------------------------------------------------------------------------- 1 | adminMenu.push({ 2 | route: 'feeds', 3 | label: 'Feeds', 4 | description: 'import_new_posts_from_feeds' 5 | }); 6 | 7 | Meteor.startup(function () { 8 | 9 | Router.onBeforeAction(Router._filters.isAdmin, {only: ['feeds']}); 10 | 11 | // RSS Urls Admin 12 | 13 | Router.route('/feeds', { 14 | name: 'feeds', 15 | waitOn: function() { 16 | return [ 17 | Meteor.subscribe('feeds'), 18 | Meteor.subscribe('allUsersAdmin') 19 | ]; 20 | }, 21 | template: getTemplate('feeds') 22 | }); 23 | 24 | }); 25 | -------------------------------------------------------------------------------- /packages/telescope-post-by-feed/lib/client/scss/feeds.scss: -------------------------------------------------------------------------------- 1 | $light-yellow:#fffcea; 2 | 3 | .add-feed{ 4 | background: $light-yellow; 5 | } -------------------------------------------------------------------------------- /packages/telescope-post-by-feed/lib/client/templates/feed_item.html: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /packages/telescope-post-by-feed/lib/client/templates/feed_item.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function () { 2 | Template[getTemplate('feedItem')].helpers({ 3 | formId: function () { 4 | return 'updateFeed-'+ this._id 5 | } 6 | }); 7 | 8 | Template[getTemplate('feedItem')].events({ 9 | 'click .delete-link': function(e, instance){ 10 | e.preventDefault(); 11 | if (confirm("Delete feed?")) { 12 | Feeds.remove(instance.data._id); 13 | } 14 | } 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/telescope-post-by-feed/lib/client/templates/feeds.html: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /packages/telescope-post-by-feed/lib/client/templates/feeds.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function () { 2 | Template[getTemplate('feeds')].helpers({ 3 | feeds: function(){ 4 | return Feeds.find({}, {sort: {url: 1}}); 5 | }, 6 | feedItem: function () { 7 | return getTemplate('feedItem'); 8 | } 9 | }); 10 | 11 | Template[getTemplate('feeds')].events({ 12 | 'click input[type=submit]': function(e){ 13 | e.preventDefault(); 14 | 15 | var url = $('#url').val(); 16 | 17 | Meteor.call('insertFeed', {url: url}, function(error, result) { 18 | if(error){ 19 | console.log(error); 20 | flashMessage(error.reason, "error"); 21 | clearSeenMessages(); 22 | }else{ 23 | $('#url').val(''); 24 | } 25 | }); 26 | } 27 | }); 28 | }); 29 | -------------------------------------------------------------------------------- /packages/telescope-post-by-feed/lib/server/cron.js: -------------------------------------------------------------------------------- 1 | SyncedCron.options = { 2 | log: false, 3 | collectionName: 'cronHistory', 4 | utc: false, 5 | collectionTTL: 172800 6 | } 7 | 8 | var addJob = function () { 9 | SyncedCron.add({ 10 | name: 'Post by RSS feed', 11 | schedule: function(parser) { 12 | return parser.text('every 30 minutes'); 13 | }, 14 | job: function() { 15 | if (Feeds.find().count()) { 16 | fetchFeeds(); 17 | } 18 | } 19 | }); 20 | } 21 | 22 | Meteor.startup(function () { 23 | addJob(); 24 | }) 25 | -------------------------------------------------------------------------------- /packages/telescope-post-by-feed/lib/server/publications.js: -------------------------------------------------------------------------------- 1 | Meteor.publish('feeds', function() { 2 | if(isAdminById(this.userId)){ 3 | return Feeds.find(); 4 | } 5 | return []; 6 | }); 7 | -------------------------------------------------------------------------------- /packages/telescope-post-by-feed/package-tap.i18n: -------------------------------------------------------------------------------- 1 | { 2 | "translation_function_name": "__", 3 | "helper_name": "_", 4 | "namespace": "project" 5 | } -------------------------------------------------------------------------------- /packages/telescope-releases/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/telescope-releases/i18n/en.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "telescope_has_been_updated": "Telescope has been updated." 3 | } -------------------------------------------------------------------------------- /packages/telescope-releases/lib/client/scss/releases.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/packages/telescope-releases/lib/client/scss/releases.scss -------------------------------------------------------------------------------- /packages/telescope-releases/lib/client/templates/current_release.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/telescope-releases/lib/client/templates/current_release.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function () { 2 | 3 | Template[getTemplate('currentRelease')].created = function () { 4 | this.release = function () { 5 | return Releases.find({read: false}).fetch()[0]; 6 | } 7 | }; 8 | 9 | Template[getTemplate('currentRelease')].helpers({ 10 | currentRelease: function () { 11 | return Template.instance().release(); 12 | } 13 | }); 14 | 15 | Template[getTemplate('currentRelease')].events({ 16 | 'click .release-dismiss': function (event, instance) { 17 | event.preventDefault(); 18 | Releases.update(instance.release()._id, {$set: {read: true}}); 19 | } 20 | }) 21 | 22 | }); 23 | -------------------------------------------------------------------------------- /packages/telescope-releases/lib/releases.js: -------------------------------------------------------------------------------- 1 | Releases = new Meteor.Collection('releases'); 2 | 3 | heroModules.push({ 4 | template: 'currentRelease' 5 | }); 6 | 7 | preloadSubscriptions.push('currentRelease'); 8 | 9 | Meteor.startup(function () { 10 | Releases.allow({ 11 | insert: isAdminById, 12 | update: isAdminById, 13 | remove: isAdminById 14 | }); 15 | }); 16 | -------------------------------------------------------------------------------- /packages/telescope-releases/lib/server/import_releases.js: -------------------------------------------------------------------------------- 1 | importRelease = function (number) { 2 | var releaseNotes = Assets.getText("releases/" + number + ".md"); 3 | 4 | if (!Releases.findOne({number: number})) { 5 | 6 | release = { 7 | number: number, 8 | notes: releaseNotes, 9 | createdAt: new Date(), 10 | read: false 11 | } 12 | Releases.insert(release); 13 | 14 | } else { 15 | 16 | // if release note already exists, update its content in case it's been updated 17 | Releases.update({number: number}, {$set: {notes: releaseNotes}}) 18 | 19 | } 20 | }; 21 | 22 | Meteor.startup(function () { 23 | 24 | importRelease('0.11.0'); 25 | importRelease('0.11.1'); 26 | importRelease('0.12.0'); 27 | importRelease('0.13.0'); 28 | importRelease('0.14.0'); 29 | 30 | // if this is before the first run, mark all release notes as read to avoid showing them 31 | if (!Events.findOne({name: 'firstRun'})) { 32 | var r = Releases.update({}, {$set: {read: true}}, {multi: true}); 33 | } 34 | 35 | }); -------------------------------------------------------------------------------- /packages/telescope-releases/lib/server/publications.js: -------------------------------------------------------------------------------- 1 | Meteor.publish('currentRelease', function() { 2 | if(isAdminById(this.userId)){ 3 | return Releases.find({}, {sort: {createdAt: -1}, limit: 1}); 4 | } 5 | return []; 6 | }); -------------------------------------------------------------------------------- /packages/telescope-releases/package-tap.i18n: -------------------------------------------------------------------------------- 1 | { 2 | "translation_function_name": "__", 3 | "helper_name": "_", 4 | "namespace": "project" 5 | } -------------------------------------------------------------------------------- /packages/telescope-releases/releases/0.11.0.md: -------------------------------------------------------------------------------- 1 | ### v0.11.0 “AvatarScope” 2 | 3 | * Added new `userCreatedCallbacks` callback hook. 4 | * Added new setting to subscribe new user to mailing list automatically. 5 | * Added new `debug` setting. 6 | * `siteUrl` setting now affects `Meteor.absoluteUrl()`. 7 | * Added new `clog` function that only logs if `debug` setting is true. 8 | * Simplified post module system, modules are not split in three zones anymore. 9 | * Added new `postThumbnail` hook to show Embedly thumbnail. 10 | * Simplified Hubble theme CSS for both desktop and mobile. 11 | * Many CSS tweaks for Hubble mobile. 12 | * Show author and commenters avatars on post item. 13 | * Adding description to post list pages and showing them in menus. 14 | * Improved Russian translation (thanks @Viktorminator!). 15 | * Now using `editorconfig` (thanks @erasaur!). 16 | * Upgraded to `useraccounts:unstyled@1.4.0` (thanks @splendido!). -------------------------------------------------------------------------------- /packages/telescope-releases/releases/0.11.1.md: -------------------------------------------------------------------------------- 1 | ### v0.11.1 “FeedScope” 2 | 3 | * Post submit and edit forms now submit to their respective methods directly. 4 | * Removed `postSubmitRenderedCallbacks` and `postEditRenderedCallbacks`. 5 | * `telescope-post-by-feed` package now lets you import posts from RSS feeds. 6 | * Adding limit of 200 posts to post list request. 7 | * Refactoring post and comment submit to fix latency compensation issues. 8 | * Tags package now using Autoform. -------------------------------------------------------------------------------- /packages/telescope-releases/releases/0.12.0.md: -------------------------------------------------------------------------------- 1 | ### v0.12.0 “DummyScope” 2 | 3 |

Important: existing newsletters and feeds need to be manually re-enabled in the Settings panel.

4 | 5 | * Added "Enable Newsletter" setting. Note: existing newsletters must be re-enabled. 6 | * Added "Enable Feeds" settings. Note: existing feeds must be re-enabled. 7 | * Now showing release notes for latest version right inside the app. 8 | * Added dummy posts, users, and comments. 9 | * Added new Events collection for keeping track of important events. 10 | * Log first run event. 11 | * `MAIL_URL` environment variable can now be set from Settings. 12 | * Renamed `viewNav` to `viewsMenu`. 13 | * Renamed `adminNav` to `adminMenu`. 14 | * **New and improved [documentation](http://telesc.pe/docs).** -------------------------------------------------------------------------------- /packages/telescope-releases/releases/0.13.0.md: -------------------------------------------------------------------------------- 1 | ### v0.13.0 “ComponentScope” 2 | 3 | * Tweaked comments layout in Hubbble theme. 4 | * Added Bulgarian translation (thanks @toome123!). 5 | * Cleaned up permission functions (thanks @anthonymayer!). 6 | * Various fixes (thanks @comerc and @Kikobeats!). 7 | * Stopped synced-cron message logging. 8 | * Limit all posts lists to 200 posts. 9 | * Refactored posts lists to use the template-level subscription pattern when appropriate. 10 | * Refactored `single day` and `daily` packages. 11 | * Footer field now accepts Markdown instead of HTML. 12 | * Feeds can now be assigned to a user. 13 | * Various CSS tweaks. 14 | * Fixing newsletter issue. 15 | * Post rank now has its own module. 16 | * Changed how field label i18n works. -------------------------------------------------------------------------------- /packages/telescope-releases/releases/0.14.0.md: -------------------------------------------------------------------------------- 1 | ### v0.14.0 “GridScope” 2 | 3 | * Adeed Grid Layout option. 4 | * Cleaned up vote click handling functions and added tests (thanks @anthonymayer!). 5 | * Added `threadModules` zone. 6 | * Added `upvoteCallbacks` and `downvoteCallbacks` callback arrays. 7 | * Fix “post awaiting moderation” message bug. 8 | * You can now subscribe to comment threads (thanks @delgermurun!). 9 | * Added `postApproveCallbacks` callback array. 10 | * Added notifications for pending and approved posts, for admins and end users. 11 | * Renaming "digest" view to "singleday". 12 | * Make sure only valid properties can be added to posts and comments. 13 | * Added newsletter time setting (thanks @anthonymayer!). 14 | * Change "sign up" to "register" (thanks @Kikobeats!). -------------------------------------------------------------------------------- /packages/telescope-rss/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/telescope-rss/.npm/package/.gitignore: -------------------------------------------------------------------------------- 1 | node_modules 2 | -------------------------------------------------------------------------------- /packages/telescope-rss/.npm/package/README: -------------------------------------------------------------------------------- 1 | This directory and the files immediately inside it are automatically generated 2 | when you change this package's NPM dependencies. Commit the files in this 3 | directory (npm-shrinkwrap.json, .gitignore, and this README) to source control 4 | so that others run the same versions of sub-dependencies. 5 | 6 | You should NOT check in the node_modules directory that Meteor automatically 7 | creates; if you are using git, the .gitignore file tells git to ignore it. 8 | -------------------------------------------------------------------------------- /packages/telescope-rss/.npm/package/npm-shrinkwrap.json: -------------------------------------------------------------------------------- 1 | { 2 | "dependencies": { 3 | "rss": { 4 | "version": "0.3.2", 5 | "dependencies": { 6 | "xml": { 7 | "version": "0.0.12" 8 | }, 9 | "mime": { 10 | "version": "1.2.11" 11 | } 12 | } 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /packages/telescope-rss/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({summary: "Telescope RSS package"}); 2 | 3 | Npm.depends({rss: "0.3.2"}); 4 | 5 | Package.onUse(function (api) { 6 | 7 | api.use(['telescope-base', 'telescope-lib'], ['server']); 8 | 9 | api.add_files(['lib/server/rss.js', 'lib/server/routes.js'], ['server']); 10 | 11 | api.export(['serveRSS']); 12 | }); -------------------------------------------------------------------------------- /packages/telescope-search/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/telescope-search/i18n/de.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "load_more": "Mehr Laden", 3 | "search": "Suchen" 4 | } -------------------------------------------------------------------------------- /packages/telescope-search/i18n/en.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "load_more": "Load more", 3 | "search": "Search", 4 | "search_logs": "Search Logs", 5 | "see_what_people_are_searching_for": "See what people are searching for." 6 | } -------------------------------------------------------------------------------- /packages/telescope-search/i18n/es.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "load_more": "Cargar más", 3 | "search": "Búsqueda" 4 | } -------------------------------------------------------------------------------- /packages/telescope-search/i18n/fr.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "load_more": "Charger plus", 3 | "search": "Rechercher" 4 | } -------------------------------------------------------------------------------- /packages/telescope-search/i18n/it.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "load_more": "Carica altro", 3 | "search": "Ricerca" 4 | } -------------------------------------------------------------------------------- /packages/telescope-search/i18n/tr.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "load_more": "Daha Fazla yükle", 3 | "search": "Search" 4 | } -------------------------------------------------------------------------------- /packages/telescope-search/i18n/zh-CN.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "load_more": "加载更多", 3 | "search": "Search" 4 | } -------------------------------------------------------------------------------- /packages/telescope-search/lib/client/css/search.css: -------------------------------------------------------------------------------- 1 | .mobile-nav .search{ 2 | padding: 10px; 3 | } 4 | .search-field{ 5 | color: #4a4444; 6 | border: 1px solid rgba(0,0,0,0.2); 7 | } -------------------------------------------------------------------------------- /packages/telescope-search/lib/client/routes.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function () { 2 | 3 | PostsSearchController = PostsListController.extend({ 4 | view: 'search', 5 | onBeforeAction: function() { 6 | var query = this.params.query; 7 | if ('q' in query) { 8 | Session.set('searchQuery', query.q); 9 | if (query.q) { 10 | Meteor.call('logSearch', query.q) 11 | } 12 | } 13 | this.next(); 14 | } 15 | }); 16 | 17 | Router.onBeforeAction(Router._filters.isAdmin, {only: ['logs']}); 18 | 19 | // Search 20 | 21 | Router.route('/search/:limit?', { 22 | name: 'search', 23 | controller: PostsSearchController 24 | }); 25 | 26 | // Search Logs 27 | 28 | Router.route('/logs/:limit?', { 29 | name: 'searchLogs', 30 | waitOn: function () { 31 | var limit = this.params.limit || 100; 32 | if(Meteor.isClient) { 33 | Session.set('logsLimit', limit); 34 | } 35 | return Meteor.subscribe('searches', limit); 36 | }, 37 | data: function () { 38 | return Searches.find({}, {sort: {timestamp: -1}}); 39 | }, 40 | fastRender: true 41 | }); 42 | 43 | }); 44 | -------------------------------------------------------------------------------- /packages/telescope-search/lib/client/views/search.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/telescope-search/lib/client/views/search_logs.html: -------------------------------------------------------------------------------- 1 | 33 | -------------------------------------------------------------------------------- /packages/telescope-search/lib/client/views/search_logs.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function () { 2 | Template[getTemplate('searchLogs')].helpers({ 3 | getTime: function () { 4 | return moment(this.timestamp).format("HH:mm:ss"); 5 | }, 6 | getDate: function () { 7 | currentDate = moment(this.timestamp).format("MMMM DD"); 8 | return currentDate; 9 | }, 10 | searchCount: function () { 11 | // TODO: doesn't work properly with "load more" 12 | var after = moment(this.timestamp).startOf('day').valueOf(), 13 | before = moment(this.timestamp).endOf('day').valueOf(); 14 | 15 | return Searches.find({ 16 | timestamp: { 17 | $gte: after, 18 | $lt: before 19 | } 20 | }).count(); 21 | }, 22 | isNewDate: function () { 23 | return (typeof currentDate === 'undefined') ? true : (currentDate !== moment(this.timestamp).format("MMMM DD")); 24 | }, 25 | loadMoreUrl: function() { 26 | var count = parseInt(Session.get('logsLimit')) + 100; 27 | return '/logs/' + count; 28 | }, 29 | }); 30 | }); -------------------------------------------------------------------------------- /packages/telescope-search/lib/server/log_search.js: -------------------------------------------------------------------------------- 1 | var logSearch = function (keyword) { 2 | Searches.insert({ 3 | timestamp: new Date(), 4 | keyword: keyword 5 | }); 6 | }; 7 | 8 | Meteor.methods({ 9 | logSearch: function (keyword) { 10 | logSearch.call(this, keyword); 11 | } 12 | }); -------------------------------------------------------------------------------- /packages/telescope-search/lib/server/publications.js: -------------------------------------------------------------------------------- 1 | Meteor.publish('searches', function(limit) { 2 | var limit = typeof limit === undefined ? 20 : limit; 3 | if(isAdminById(this.userId)){ 4 | return Searches.find({}, {limit: limit, sort: {timestamp: -1}}); 5 | } 6 | return []; 7 | }); -------------------------------------------------------------------------------- /packages/telescope-search/package-tap.i18n: -------------------------------------------------------------------------------- 1 | { 2 | "translation_function_name": "__", 3 | "helper_name": "_", 4 | "namespace": "project" 5 | } -------------------------------------------------------------------------------- /packages/telescope-search/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({summary: "Telescope search package"}); 2 | 3 | Package.onUse(function (api) { 4 | 5 | api.use(['telescope-lib', 'telescope-base', 'aldeed:simple-schema'], ['client', 'server']); 6 | 7 | api.use([ 8 | 'jquery', 9 | 'underscore', 10 | 'iron:router', 11 | 'templating', 12 | 'tap:i18n' 13 | ], 'client'); 14 | 15 | api.add_files([ 16 | 'lib/search.js', 17 | 'package-tap.i18n' 18 | ], ['client', 'server']); 19 | 20 | api.add_files([ 21 | 'lib/client/routes.js', 22 | 'lib/client/views/search.html', 23 | 'lib/client/views/search.js', 24 | 'lib/client/css/search.css', 25 | 'lib/client/views/search_logs.html', 26 | 'lib/client/views/search_logs.js' 27 | ], ['client']); 28 | 29 | api.add_files([ 30 | 'lib/server/log_search.js', 31 | 'lib/server/publications.js' 32 | ], ['server']); 33 | 34 | api.add_files([ 35 | "i18n/de.i18n.json", 36 | "i18n/en.i18n.json", 37 | "i18n/es.i18n.json", 38 | "i18n/fr.i18n.json", 39 | "i18n/it.i18n.json", 40 | "i18n/zh-CN.i18n.json", 41 | ], ["client", "server"]); 42 | 43 | api.export(['adminMenu', 'viewParameters']); 44 | }); -------------------------------------------------------------------------------- /packages/telescope-singleday/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/telescope-singleday/i18n/de.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "the_top_5_posts_of_each_day": "Die Top-5-Links eines jeden Tages.", 3 | "previous_day": "Einen Tag zurück", 4 | "next_day": "Einen Tag vor", 5 | "sorry_no_posts_for_today": "Heute gibt es keine Links.", 6 | "sorry_no_posts_for": "Keine Links für", 7 | "today": "Heute", 8 | "yesterday": "Gestern" 9 | } -------------------------------------------------------------------------------- /packages/telescope-singleday/i18n/en.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "the_top_5_posts_of_each_day": "The top 5 posts of each day.", 3 | "previous_day": "Previous Day", 4 | "next_day": "Next Day", 5 | "sorry_no_posts_for_today": "Sorry, no posts for today", 6 | "sorry_no_posts_for": "Sorry, no posts for", 7 | "today": "Today", 8 | "yesterday": "Yesterday", 9 | "single_day": "Single Day", 10 | "posts_of_a_single_day": "The posts of a single day." 11 | } -------------------------------------------------------------------------------- /packages/telescope-singleday/i18n/es.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "the_top_5_posts_of_each_day": "Los 5 mejores posts de cada día", 3 | "previous_day": "Dia anterior", 4 | "next_day": "Dia siguiente", 5 | "sorry_no_posts_for_today": "Lo sentimos, no hay post para hoy", 6 | "today": "Hoy", 7 | "yesterday": "Ayer" 8 | } -------------------------------------------------------------------------------- /packages/telescope-singleday/i18n/fr.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "the_top_5_posts_of_each_day": "5 meilleurs post par jours", 3 | "previous_day": "Jour précédent", 4 | "next_day": "Jour suivant", 5 | "sorry_no_posts_for_today": "Désolé, aucun post aujourd'hui", 6 | "sorry_no_posts_for": "Désolé, aucun post pour", 7 | "today": "Aujourd'hui", 8 | "yesterday": "Hier" 9 | } -------------------------------------------------------------------------------- /packages/telescope-singleday/i18n/it.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "the_top_5_posts_of_each_day": "I 5 migliori post di ogni giorno.", 3 | "previous_day": "Giorno Precedente", 4 | "next_day": "Giorno Successivo", 5 | "sorry_no_posts_for_today": "Ci spiace, non ci sono post per oggi", 6 | "sorry_no_posts_for": "Ci spiace, non ci sono post per", 7 | "today": "Oggi", 8 | "yesterday": "Ieri" 9 | } -------------------------------------------------------------------------------- /packages/telescope-singleday/i18n/tr.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "the_top_5_posts_of_each_day": "Her günün en üst 5 paylaşımı", 3 | "previous_day": "Önceki gün", 4 | "next_day": "Sonraki gün", 5 | "Sorry, no posts for today": "Özür dileriz, bugün bir paylaşım yok", 6 | "sorry_no_posts_for_today": "Özür dileriz, paylaşım yok", 7 | "today": "Bugün", 8 | "yesterday": "Dün" 9 | } -------------------------------------------------------------------------------- /packages/telescope-singleday/i18n/zh-CN.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "the_top_5_posts_of_each_day": "每天前5名的帖子", 3 | "previous_day": "前一天", 4 | "next_day": "后一天", 5 | "sorry_no_posts_for_today": "抱歉今天没有新的帖子", 6 | "today": "今天", 7 | "yesterday": "昨天" 8 | } -------------------------------------------------------------------------------- /packages/telescope-singleday/lib/client/templates/single_day.html: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /packages/telescope-singleday/lib/client/templates/single_day_nav.html: -------------------------------------------------------------------------------- 1 | 14 | -------------------------------------------------------------------------------- /packages/telescope-singleday/lib/routes.js: -------------------------------------------------------------------------------- 1 | // Controller for post digest 2 | 3 | PostsSingleDayController = RouteController.extend({ 4 | 5 | template: getTemplate('singleDay'), 6 | 7 | data: function() { 8 | var currentDate = this.params.day ? new Date(this.params.year, this.params.month-1, this.params.day) : Session.get('today'); 9 | Session.set('currentDate', currentDate); 10 | }, 11 | 12 | getTitle: function () { 13 | return i18n.t('single_day') + ' - ' + getSetting('title', 'Telescope'); 14 | }, 15 | 16 | getDescription: function () { 17 | return i18n.t('posts_of_a_single_day'); 18 | }, 19 | 20 | fastRender: true 21 | 22 | }); 23 | 24 | Meteor.startup(function () { 25 | 26 | // Digest 27 | 28 | Router.route('/day/:year/:month/:day', { 29 | name: 'postsSingleDay', 30 | controller: PostsSingleDayController 31 | }); 32 | 33 | Router.route('/day', { 34 | name: 'postsSingleDayDefault', 35 | controller: PostsSingleDayController 36 | }); 37 | 38 | }); -------------------------------------------------------------------------------- /packages/telescope-singleday/lib/singleday.js: -------------------------------------------------------------------------------- 1 | viewsMenu.push({ 2 | route: 'postsSingleDayDefault', 3 | label: 'digest', 4 | description: 'posts_of_a_single_day' 5 | }); 6 | 7 | viewParameters.singleday = function (terms) { 8 | return { 9 | find: { 10 | postedAt: { 11 | $gte: terms.after, 12 | $lt: terms.before 13 | } 14 | }, 15 | options: { 16 | sort: {sticky: -1, score: -1} 17 | } 18 | }; 19 | }; 20 | 21 | getDateURL = function(moment){ 22 | return Router.path('postsSingleDay', { 23 | year: moment.year(), 24 | month: moment.month() + 1, 25 | day: moment.date() 26 | }); 27 | }; -------------------------------------------------------------------------------- /packages/telescope-singleday/package-tap.i18n: -------------------------------------------------------------------------------- 1 | { 2 | "translation_function_name": "__", 3 | "helper_name": "_", 4 | "namespace": "project" 5 | } -------------------------------------------------------------------------------- /packages/telescope-subscribe-to-posts/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/telescope-subscribe-to-posts/i18n/en.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "subscribed_posts": "Subscribed Posts", 3 | "subscribe_to_thread": "Subscribe to comment thread", 4 | "unsubscribe_from_thread": "Unsubscribe from comment thread" 5 | } -------------------------------------------------------------------------------- /packages/telescope-subscribe-to-posts/lib/client/stylesheets/subscribe-to-posts.scss: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/packages/telescope-subscribe-to-posts/lib/client/stylesheets/subscribe-to-posts.scss -------------------------------------------------------------------------------- /packages/telescope-subscribe-to-posts/lib/client/templates/post_subscribe.html: -------------------------------------------------------------------------------- 1 | 16 | -------------------------------------------------------------------------------- /packages/telescope-subscribe-to-posts/lib/client/templates/user_subscribed_posts.html: -------------------------------------------------------------------------------- 1 | 27 | -------------------------------------------------------------------------------- /packages/telescope-subscribe-to-posts/lib/server/publications.js: -------------------------------------------------------------------------------- 1 | Meteor.publish('userSubscribedPosts', function(terms) { 2 | var parameters = getPostsParameters(terms); 3 | var posts = Posts.find(parameters.find, parameters.options); 4 | return posts; 5 | }); 6 | -------------------------------------------------------------------------------- /packages/telescope-subscribe-to-posts/package-tap.i18n: -------------------------------------------------------------------------------- 1 | { 2 | "translation_function_name": "__", 3 | "helper_name": "_", 4 | "namespace": "project" 5 | } -------------------------------------------------------------------------------- /packages/telescope-tags/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/telescope-tags/i18n/de.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "categories": "Kategorien" 3 | } -------------------------------------------------------------------------------- /packages/telescope-tags/i18n/en.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "categories": "Categories", 3 | "add_and_remove_categories": "Add and remove categories." 4 | } -------------------------------------------------------------------------------- /packages/telescope-tags/i18n/es.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "categories": "Categorías" 3 | } -------------------------------------------------------------------------------- /packages/telescope-tags/i18n/fr.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "categories": "Catégories" 3 | } -------------------------------------------------------------------------------- /packages/telescope-tags/i18n/it.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "categories": "Categorie" 3 | } -------------------------------------------------------------------------------- /packages/telescope-tags/i18n/zh-CN.i18n.json: -------------------------------------------------------------------------------- 1 | { 2 | "categories": "分类" 3 | } -------------------------------------------------------------------------------- /packages/telescope-tags/lib/client/routes.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function () { 2 | 3 | Router.onBeforeAction(Router._filters.isAdmin, {only: ['categories']}); 4 | 5 | PostsCategoryController = PostsListController.extend({ 6 | 7 | view: 'category', 8 | 9 | getCurrentCategory: function () { 10 | return Categories.findOne({slug: this.params.slug}); 11 | }, 12 | 13 | getTitle: function () { 14 | var category = this.getCurrentCategory(); 15 | return category.name + ' - ' + getSetting('title', 'Telescope'); 16 | }, 17 | 18 | getDescription: function () { 19 | return this.getCurrentCategory().description; 20 | } 21 | 22 | }); 23 | 24 | // Categories 25 | 26 | Router.route('/category/:slug/:limit?', { 27 | name: 'posts_category', 28 | controller: PostsCategoryController, 29 | onAfterAction: function() { 30 | this.slug = this.params.slug; 31 | Session.set('categorySlug', this.params.slug); 32 | } 33 | }); 34 | 35 | // Categories Admin 36 | 37 | Router.route('/categories', { 38 | name: 'categories' 39 | }); 40 | 41 | 42 | }); -------------------------------------------------------------------------------- /packages/telescope-tags/lib/client/scss/categories.scss: -------------------------------------------------------------------------------- 1 | $red: #DD3416; 2 | $light-yellow:#fffcea; 3 | 4 | .post-category{ 5 | display:inline-block; 6 | font-size:12px; 7 | background:#eee; 8 | padding:3px 5px 1px 5px; 9 | text-transform:uppercase; 10 | font-weight:normal; 11 | vertical-align:middle; 12 | &:hover{ 13 | background:$red; 14 | color:white; 15 | } 16 | } 17 | 18 | .add-category{ 19 | background: $light-yellow; 20 | } 21 | 22 | .post-categories{ 23 | text-align: right; 24 | } -------------------------------------------------------------------------------- /packages/telescope-tags/lib/client/templates/categories.html: -------------------------------------------------------------------------------- 1 | 10 | -------------------------------------------------------------------------------- /packages/telescope-tags/lib/client/templates/categories.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function () { 2 | Template[getTemplate('categories')].helpers({ 3 | categories: function(){ 4 | return Categories.find({}, {sort: {order: 1, name: 1}}); 5 | }, 6 | categoryItem: function () { 7 | return getTemplate('categoryItem'); 8 | } 9 | }); 10 | 11 | Template[getTemplate('categories')].events({ 12 | 'click input[type=submit]': function(e){ 13 | e.preventDefault(); 14 | 15 | var name = $('#name').val(); 16 | var numberOfCategories = Categories.find().count(); 17 | var order = parseInt($('#order').val()) || (numberOfCategories + 1); 18 | var slug = slugify(name); 19 | 20 | Meteor.call('submitCategory', { 21 | name: name, 22 | order: order, 23 | slug: slug 24 | }, function(error, categoryName) { 25 | if(error){ 26 | console.log(error); 27 | flashMessage(error.reason, "error"); 28 | clearSeenMessages(); 29 | }else{ 30 | $('#name').val(''); 31 | // flashMessage('New category "'+categoryName+'" created', "success"); 32 | } 33 | }); 34 | } 35 | }); 36 | }); 37 | -------------------------------------------------------------------------------- /packages/telescope-tags/lib/client/templates/categories_menu.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/telescope-tags/lib/client/templates/categories_menu.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function () { 2 | Template[getTemplate('categoriesMenu')].helpers({ 3 | hasCategories: function(){ 4 | return typeof Categories !== 'undefined' && Categories.find().count(); 5 | }, 6 | cat: function () { 7 | return __('categories') 8 | }, 9 | categories: function(){ 10 | return Categories.find({}, {sort: {order: 1, name: 1}}); 11 | }, 12 | categoryLink: function () { 13 | return getCategoryUrl(this.slug); 14 | } 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/telescope-tags/lib/client/templates/category_item.html: -------------------------------------------------------------------------------- 1 | 7 | -------------------------------------------------------------------------------- /packages/telescope-tags/lib/client/templates/category_item.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function () { 2 | Template[getTemplate('categoryItem')].helpers({ 3 | formId: function () { 4 | return 'updateCategory-'+ this._id 5 | } 6 | }); 7 | 8 | Template[getTemplate('categoryItem')].events({ 9 | 'click .delete-link': function(e, instance){ 10 | e.preventDefault(); 11 | if (confirm("Delete category?")) { 12 | Categories.remove(instance.data._id); 13 | } 14 | } 15 | }); 16 | }); 17 | -------------------------------------------------------------------------------- /packages/telescope-tags/lib/client/templates/post_categories.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/telescope-tags/lib/client/templates/post_categories.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function () { 2 | Template[getTemplate('postCategories')].helpers({ 3 | categoriesArray: function(){ 4 | return _.map(this.categories, function (categoryId) { // note: this.categories maybe be undefined 5 | return Categories.findOne(categoryId); 6 | }); 7 | }, 8 | categoryLink: function(){ 9 | return getCategoryUrl(this.slug); 10 | } 11 | }); 12 | }); -------------------------------------------------------------------------------- /packages/telescope-tags/lib/custom_fields.js: -------------------------------------------------------------------------------- 1 | addToPostSchema.push( 2 | { 3 | propertyName: 'categories', 4 | propertySchema: { 5 | type: [String], 6 | optional: true, 7 | editable: true, 8 | autoform: { 9 | editable: true, 10 | noselect: true, 11 | options: function () { 12 | var categories = Categories.find().map(function (category) { 13 | return { 14 | value: category._id, 15 | label: category.name 16 | } 17 | }); 18 | return categories; 19 | } 20 | } 21 | } 22 | } 23 | ); -------------------------------------------------------------------------------- /packages/telescope-tags/lib/hooks.js: -------------------------------------------------------------------------------- 1 | adminMenu.push({ 2 | route: 'categories', 3 | label: 'Categories', 4 | description: 'add_and_remove_categories' 5 | }); 6 | 7 | // push "categories" modules to postHeading 8 | postHeading.push({ 9 | template: 'postCategories', 10 | order: 30 11 | }); 12 | 13 | // push "categoriesMenu" template to primaryNav 14 | primaryNav.push({ 15 | template: 'categoriesMenu', 16 | order: 50 17 | }); 18 | 19 | // we want to wait until categories are all loaded to load the rest of the app 20 | preloadSubscriptions.push('categories'); 21 | -------------------------------------------------------------------------------- /packages/telescope-tags/lib/server/publications.js: -------------------------------------------------------------------------------- 1 | Meteor.publish('categories', function() { 2 | if(can.viewById(this.userId)){ 3 | return Categories.find(); 4 | } 5 | return []; 6 | }); -------------------------------------------------------------------------------- /packages/telescope-tags/package-tap.i18n: -------------------------------------------------------------------------------- 1 | { 2 | "translation_function_name": "__", 3 | "helper_name": "_", 4 | "namespace": "project" 5 | } -------------------------------------------------------------------------------- /packages/telescope-theme-base/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/telescope-theme-base/lib/client/scss/global/_links.scss: -------------------------------------------------------------------------------- 1 | a{ 2 | text-decoration: none; 3 | &, &:link, &:visited, &:active{ 4 | color: $text; 5 | font-weight: bold; 6 | } 7 | &:hover{ 8 | color: $red; 9 | } 10 | } -------------------------------------------------------------------------------- /packages/telescope-theme-base/lib/client/scss/global/_main.scss: -------------------------------------------------------------------------------- 1 | .hidden{ 2 | display:none; 3 | } 4 | .visible{ 5 | display: block; 6 | } 7 | .overlay{ 8 | position:fixed; 9 | top:0; 10 | left:0; 11 | height:100%; 12 | width:100%; 13 | z-index:50; 14 | } 15 | 16 | #spinner{ 17 | margin: 100px 0; 18 | } 19 | .debug{ 20 | display:none; 21 | } 22 | 23 | .footer{ 24 | text-align:center; 25 | padding:10px 0 70px 0; 26 | color:black(0.4); 27 | font-size:14px; 28 | &.absolute{ 29 | position:absolute; 30 | } 31 | } 32 | #login-buttons .loading{ 33 | display:none; 34 | } 35 | #loading, .loading-page{ 36 | height:300px; 37 | } 38 | 39 | .notifications-toggle{ 40 | background: white; 41 | margin-bottom: $grid-margin; 42 | padding: $grid-padding; 43 | } 44 | 45 | .search-date-header{ 46 | background: $lightest-grey; 47 | th{ 48 | @include cf; 49 | } 50 | .search-date{ 51 | display: block; 52 | float: left; 53 | font-weight: bold; 54 | } 55 | .search-count{ 56 | font-size: 13px; 57 | display: block; 58 | float: right; 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /packages/telescope-theme-base/lib/client/scss/global/_tables.scss: -------------------------------------------------------------------------------- 1 | table{ 2 | width: 100%; 3 | tr{ 4 | border-bottom: 1px solid #eee; 5 | td, th{ 6 | padding:10px; 7 | vertical-align: middle; 8 | } 9 | } 10 | thead{ 11 | tr{ 12 | td, th{ 13 | font-weight:bold; 14 | } 15 | } 16 | } 17 | tbody{ 18 | tr{ 19 | td{ 20 | 21 | } 22 | } 23 | } 24 | } -------------------------------------------------------------------------------- /packages/telescope-theme-base/lib/client/scss/global/_typography.scss: -------------------------------------------------------------------------------- 1 | html, body, input, button{ 2 | font-family: "Helvetica Neue", Helvetica, Arial, sans-serif; 3 | } 4 | h1,h2,h3,h4,h5, ul, ol, li, p, pre, div{ 5 | line-height: 1.5; 6 | } 7 | h1{ 8 | font-size: 40px; 9 | } 10 | h2{ 11 | font-size: 30px; 12 | } 13 | h3{ 14 | font-size: 20px; 15 | } 16 | h4{ 17 | font-size: 16px; 18 | } 19 | li{ 20 | margin: 0 0 10px 0; 21 | } 22 | .important{ 23 | color: $red; 24 | } -------------------------------------------------------------------------------- /packages/telescope-theme-base/lib/client/scss/includes/_breakpoints.scss: -------------------------------------------------------------------------------- 1 | $grid-unit:70px; 2 | $grid-margin:10px; 3 | $grid-padding:15px; 4 | $break-small:500px; 5 | 6 | $small-break: 40em; 7 | $medium-break: 50em; 8 | 9 | @mixin small(){ 10 | @media screen and (max-width: $small-break) { 11 | @content; 12 | } 13 | } 14 | @mixin small-medium(){ 15 | @media screen and (max-width: $medium-break) { 16 | @content; 17 | } 18 | } 19 | @mixin medium(){ 20 | @media screen and (min-width: $small-break) and (max-width: $medium-break) { 21 | @content; 22 | } 23 | } 24 | @mixin medium-large(){ 25 | @media screen and (min-width: $small-break) { 26 | @content; 27 | } 28 | } 29 | @mixin large(){ 30 | @media screen and (min-width: $medium-break) { 31 | @content; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /packages/telescope-theme-base/lib/client/scss/includes/_colors.scss: -------------------------------------------------------------------------------- 1 | $red: #DD3416; 2 | $green:#a3d06d; 3 | 4 | $blue:#7ac0e4; 5 | $dark-blue:#4e555d; 6 | $blue-grey:#b3c1c6; 7 | $blue-grey2:#a4a9ab; 8 | $light-blue:#d8e9f5; 9 | $light-blue2:#92b5c3; 10 | 11 | $yellow:#f8e121; 12 | $light-yellow:#fffcea; 13 | 14 | $grey:#b5b0b0; 15 | $lighter-grey:#dfdbdb; 16 | $lightest-grey:#e7eff2; 17 | $dark-grey:#444444; 18 | 19 | $header-bg:$dark-grey; 20 | $text:$dark-grey; 21 | $medium-text:$blue-grey2; 22 | $light-text:$blue-grey; 23 | $lighter-text:$lighter-grey; 24 | $border-color:$grey; 25 | $highlight-color:$dark-blue; -------------------------------------------------------------------------------- /packages/telescope-theme-base/lib/client/scss/screen.scss: -------------------------------------------------------------------------------- 1 | // Includes 2 | 3 | @import "includes/breakpoints"; 4 | @import "includes/colors"; 5 | @import "includes/mixins"; 6 | 7 | // Global Styles (forms, typography, etc.) 8 | 9 | @import "global/forms"; 10 | @import "global/links"; 11 | @import "global/main"; 12 | @import "global/markdown"; 13 | @import "global/tables"; 14 | @import "global/typography"; 15 | 16 | // Specific Styles (header, posts, etc.) 17 | 18 | @import "specific/avatars"; 19 | @import "specific/dropdown"; 20 | @import "specific/errors"; 21 | @import "specific/header"; 22 | @import "specific/layout"; 23 | @import "specific/loading"; 24 | @import "specific/mobile_nav"; 25 | @import "specific/notifications"; 26 | @import "specific/posts"; 27 | @import "specific/users"; 28 | -------------------------------------------------------------------------------- /packages/telescope-theme-base/lib/client/scss/specific/_avatars.scss: -------------------------------------------------------------------------------- 1 | .avatar-xsmall { 2 | .avatar-initials{ 3 | font-size: 12px; 4 | line-height: 20px; 5 | } 6 | } 7 | .avatar-small { 8 | height: 24px; 9 | width: 24px; 10 | .avatar-initials{ 11 | font-size: 13px; 12 | line-height: 24px; 13 | } 14 | } 15 | .avatar-medium { 16 | height: 30px; 17 | width: 30px; 18 | .avatar-initials{ 19 | font-size: 14px; 20 | line-height: 30px; 21 | } 22 | } 23 | 24 | .avatar-initials{ 25 | font-weight: normal; 26 | } -------------------------------------------------------------------------------- /packages/telescope-theme-base/lib/client/scss/specific/_errors.scss: -------------------------------------------------------------------------------- 1 | .error, .at-error{ 2 | background: $red; 3 | color: white; 4 | } -------------------------------------------------------------------------------- /packages/telescope-theme-base/lib/client/scss/specific/_layout.scss: -------------------------------------------------------------------------------- 1 | *, *:before, *:after { 2 | box-sizing: border-box; 3 | line-height: 1.5; 4 | } 5 | 6 | html, body, .outer-wrapper{ 7 | height:100%; 8 | } 9 | 10 | body{ 11 | background:#eee; 12 | font-size: 14px; 13 | @include small{ 14 | overflow-x: hidden; 15 | } 16 | } 17 | 18 | .outer-wrapper{ 19 | position:relative; 20 | } 21 | .content-wrapper{ 22 | padding-bottom:20px; 23 | } 24 | .content-wrapper{ 25 | padding: 0 10px; 26 | max-width: 1000px; 27 | margin: 0 auto; 28 | @include small{ 29 | overflow-x: hidden; 30 | overflow-y: hidden; 31 | } 32 | } 33 | .grid-module, .at-form{ 34 | background: white; 35 | padding: $grid-padding; 36 | margin-bottom: $grid-margin; 37 | } -------------------------------------------------------------------------------- /packages/telescope-theme-base/lib/client/scss/specific/_loading.scss: -------------------------------------------------------------------------------- 1 | .loading-module{ 2 | height: 70px; 3 | position: relative; 4 | } -------------------------------------------------------------------------------- /packages/telescope-theme-base/lib/client/scss/specific/_notifications.scss: -------------------------------------------------------------------------------- 1 | .notification-item{ 2 | margin-bottom: 10px; 3 | } -------------------------------------------------------------------------------- /packages/telescope-theme-base/lib/client/scss/specific/_posts.scss: -------------------------------------------------------------------------------- 1 | .posts-wrapper{ 2 | background: none; 3 | } 4 | .more-button{ 5 | display: block; 6 | } -------------------------------------------------------------------------------- /packages/telescope-theme-base/lib/client/scss/specific/_users.scss: -------------------------------------------------------------------------------- 1 | .user-list, .user-table{ 2 | font-size: 13px; 3 | .user{ 4 | .user-avatar{ 5 | height:30px; 6 | width:30px; 7 | background-size: 30px 30px; 8 | display:block; 9 | border-radius: 30px; 10 | } 11 | .posts-list{ 12 | 13 | } 14 | } 15 | } 16 | .filter-sort{ 17 | @include cf; 18 | padding: $grid-padding; 19 | background: black(0.05); 20 | a, span{ 21 | display: inline-block; 22 | margin-right: 20px; 23 | &.active{ 24 | border-bottom: 2px solid $blue; 25 | } 26 | &:last-child{ 27 | margin-right: 0; 28 | } 29 | } 30 | .filter{ 31 | float: left; 32 | } 33 | .sort{ 34 | float: right; 35 | } 36 | 37 | } -------------------------------------------------------------------------------- /packages/telescope-theme-hubble/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | 3 | config.codekit 4 | lib/client/config.codekit -------------------------------------------------------------------------------- /packages/telescope-theme-hubble/lib/client/scss/modules/_accounts.scss: -------------------------------------------------------------------------------- 1 | .at-oauth{ 2 | text-align: center; 3 | .at-social-btn{ 4 | margin: 0 auto 15px auto; 5 | } 6 | } 7 | 8 | .at-sep{ 9 | text-align: center; 10 | position: relative; 11 | overflow: hidden; 12 | margin-bottom: 15px; 13 | &:before, &:after{ 14 | display: block; 15 | content: " "; 16 | border-bottom: 1px solid #ddd; 17 | width: 100%; 18 | position: absolute; 19 | top: 48%; 20 | } 21 | &:before{ 22 | left: -55%; 23 | } 24 | &:after{ 25 | right: -55%; 26 | } 27 | } 28 | 29 | .at-input{ 30 | label{ 31 | margin-bottom: 5px; 32 | } 33 | } 34 | 35 | #at-forgotPwd{ 36 | font-size: 13px; 37 | float: right; 38 | margin-top: -8px; 39 | } 40 | 41 | #at-btn{ 42 | margin: 0 auto; 43 | } 44 | .at-title{ 45 | border-bottom: 1px solid #ddd; 46 | margin-bottom: 20px; 47 | padding-bottom: 5px; 48 | text-align: center; 49 | } 50 | .at-signup-link, .at-signin-link{ 51 | border-top: 1px solid #ddd; 52 | margin-top: 15px; 53 | padding-top: 15px; 54 | text-align: center; 55 | } -------------------------------------------------------------------------------- /packages/telescope-theme-hubble/lib/client/scss/modules/_banners.scss: -------------------------------------------------------------------------------- 1 | .banner.banner{ 2 | background: rgba(255,255,255,0.7); 3 | margin-bottom: 10px; 4 | padding: 20px; 5 | position: relative; 6 | overflow: hidden; 7 | } 8 | 9 | .banner-heading{ 10 | border-bottom: 1px solid $grey; 11 | font-weight: bold; 12 | color: $medium-text; 13 | padding-bottom: 10px; 14 | margin-bottom: 10px; 15 | } 16 | 17 | .banner-dismiss, .banner-dismiss:link, .banner-dismiss:visited{ 18 | display: block; 19 | position: absolute; 20 | height: 30px; 21 | width: 30px; 22 | border-radius: 100%; 23 | background: rgba(0,0,0,0.15); 24 | color: white; 25 | top: 50%; 26 | margin-top: -15px; 27 | right: 20px; 28 | font-size: 24px; 29 | text-align: center; 30 | vertical-align: middle; 31 | line-height: 32px; 32 | @include small{ 33 | top: 10px; 34 | right: 10px; 35 | margin-top: 0px; 36 | } 37 | } 38 | .banner-dismiss:hover{ 39 | color: inherit; 40 | } -------------------------------------------------------------------------------- /packages/telescope-theme-hubble/lib/client/scss/modules/_dialogs.scss: -------------------------------------------------------------------------------- 1 | .dialog{ 2 | h2{ 3 | text-align:center; 4 | padding-bottom:$grid-padding; 5 | margin-bottom:$grid-margin; 6 | } 7 | margin-bottom:$grid-margin; 8 | } 9 | .footer-notice{ 10 | text-align:center; 11 | } -------------------------------------------------------------------------------- /packages/telescope-theme-hubble/lib/client/scss/modules/_errors.scss: -------------------------------------------------------------------------------- 1 | .error, .at-error{ 2 | @extend .grid-block; 3 | margin-bottom:$grid-margin; 4 | text-align:center; 5 | background:$red; 6 | color:white; 7 | } -------------------------------------------------------------------------------- /packages/telescope-theme-hubble/lib/client/scss/modules/_icons.scss: -------------------------------------------------------------------------------- 1 | .action-icon{ 2 | font-size: 30px; 3 | height: 30px; 4 | display: block; 5 | &:before{ 6 | position: relative; 7 | top: -10px; 8 | } 9 | } 10 | .action-label{ 11 | font-weight: bold; 12 | display:block; 13 | height:20px; 14 | line-height:20px; 15 | bottom:5px; 16 | left:0px; 17 | font-size:13px; 18 | color:$light-text; 19 | pointer-events:none; 20 | // color:$red; 21 | } 22 | .action-count{ 23 | position:absolute; 24 | top:4px; 25 | display:block; 26 | width:100%; 27 | height:11px; 28 | line-height:11px; 29 | font-size:14px; 30 | } -------------------------------------------------------------------------------- /packages/telescope-theme-hubble/lib/client/scss/modules/_user-profile.scss: -------------------------------------------------------------------------------- 1 | .user-profile { 2 | .user-avatar { 3 | height: 80px; 4 | width: 80px; 5 | display: block; 6 | border-radius: 80px; 7 | } 8 | } -------------------------------------------------------------------------------- /packages/telescope-theme-hubble/lib/client/scss/partials/_colors.scss: -------------------------------------------------------------------------------- 1 | $red: #DD3416; 2 | $green:#a3d06d; 3 | 4 | $blue:#7ac0e4; 5 | $dark-blue:#4e555d; 6 | $blue-grey:#b3c1c6; 7 | $blue-grey2:#a4a9ab; 8 | $light-blue:#d8e9f5; 9 | $light-blue2:#92b5c3; 10 | 11 | $yellow:#f8e121; 12 | $light-yellow:#fffce0; 13 | 14 | $grey:#b5b0b0; 15 | $lighter-grey:#dfdbdb; 16 | $lightest-grey:#e7eff2; 17 | $dark-grey:#4a4444; 18 | 19 | $header-bg:$dark-grey; 20 | $text:$dark-grey; 21 | $medium-text:$blue-grey2; 22 | $light-text:$blue-grey; 23 | $lighter-text:$lighter-grey; 24 | $border-color:$grey; 25 | $highlight-color:$dark-blue; -------------------------------------------------------------------------------- /packages/telescope-theme-hubble/lib/client/scss/partials/_grid.scss: -------------------------------------------------------------------------------- 1 | $grid-unit:70px; 2 | $grid-margin:10px; 3 | $grid-padding:15px; 4 | $break-small:500px; 5 | 6 | $small-break: 30em; 7 | $medium-break: 50em; 8 | 9 | @mixin small(){ 10 | @media screen and (max-width: $small-break) { 11 | @content; 12 | } 13 | } 14 | @mixin small-medium(){ 15 | @media screen and (max-width: $medium-break) { 16 | @content; 17 | } 18 | } 19 | @mixin medium(){ 20 | @media screen and (min-width: $small-break) and (max-width: $medium-break) { 21 | @content; 22 | } 23 | } 24 | @mixin medium-large(){ 25 | @media screen and (min-width: $small-break) { 26 | @content; 27 | } 28 | } 29 | @mixin large(){ 30 | @media screen and (min-width: $medium-break) { 31 | @content; 32 | } 33 | } 34 | 35 | .content-wrapper{ 36 | padding: 0 10px; 37 | @include small{ 38 | overflow-x: hidden; 39 | } 40 | } 41 | .grid{ 42 | width:100%; 43 | max-width: 1000px; 44 | margin-left: auto; 45 | margin-right: auto; 46 | } 47 | .grid-small, .at-form{ 48 | width: 100%; 49 | @include medium-large{ 50 | max-width:500px; 51 | } 52 | margin-left: auto; 53 | margin-right: auto; 54 | } 55 | -------------------------------------------------------------------------------- /packages/telescope-theme-hubble/lib/client/scss/partials/_tooltips.scss: -------------------------------------------------------------------------------- 1 | .has-tooltip{ 2 | position:relative; 3 | .tooltip{ 4 | pointer-events: none; 5 | position:absolute; 6 | z-index:9999; 7 | left:50%; 8 | top:-40px; 9 | opacity:0; 10 | transition: ease-out, opacity, 300ms, 0ms; 11 | span{ 12 | display:block; 13 | white-space:nowrap; 14 | position:relative; 15 | background:black(0.6); 16 | border-radius: 3px; 17 | padding:0px 8px; 18 | left:-50%; 19 | font-size:14px; 20 | color:#fff; 21 | &:after { 22 | top: 100%; 23 | border: solid transparent; 24 | content: " "; 25 | height: 0; 26 | width: 0; 27 | position: absolute; 28 | border-top-color: black(0.6); 29 | border-width: 6px; 30 | left: 50%; 31 | margin-left: -6px; 32 | } 33 | } 34 | } 35 | &:hover .tooltip{ 36 | opacity:1; 37 | } 38 | } -------------------------------------------------------------------------------- /packages/telescope-theme-hubble/lib/client/scss/partials/_typography.scss: -------------------------------------------------------------------------------- 1 | @import url(https://fonts.googleapis.com/css?family=Source+Sans+Pro:400,700,400italic,700italic); 2 | 3 | body, textarea, input, button, input[type="submit"], input[type="button"]{ 4 | font-family:"Source Sans Pro", "Helvetica Neue", Helvetica, sans-serif; 5 | } 6 | body, textarea, input{ 7 | color:$text; 8 | line-height:1.6; 9 | } 10 | .post-title, .header, .post-rank, .button{ 11 | // font-family:"kulturista-web", Rokkitt, Georgia, serif; 12 | } 13 | h2{ 14 | font-size: 36px; 15 | margin-bottom: 10px; 16 | } 17 | h3{ 18 | font-weight:bold; 19 | margin-bottom:10px; 20 | } 21 | .small{ 22 | font-size: 80%; 23 | color:$light-text; 24 | } 25 | strong{ 26 | font-weight: bold; 27 | } 28 | em{ 29 | font-style: italic; 30 | } 31 | -------------------------------------------------------------------------------- /packages/telescope-theme-hubble/lib/client/scss/screen.scss: -------------------------------------------------------------------------------- 1 | 2 | @import "partials/grid"; 3 | @import "partials/colors"; 4 | @import "partials/mixins"; 5 | @import "partials/typography"; 6 | @import "partials/icons"; 7 | @import "partials/tooltips"; 8 | 9 | @import "modules/accounts"; 10 | @import "modules/banners"; 11 | @import "modules/nav"; 12 | @import "modules/posts"; 13 | @import "modules/comments"; 14 | @import "modules/dialogs"; 15 | @import "modules/user-profile"; 16 | @import "modules/errors"; 17 | @import "modules/icons"; -------------------------------------------------------------------------------- /packages/telescope-theme-hubble/lib/hubble.js: -------------------------------------------------------------------------------- 1 | themeSettings.useDropdowns = true; // not strictly needed since "true" is the current default -------------------------------------------------------------------------------- /packages/telescope-update-prompt/.gitignore: -------------------------------------------------------------------------------- 1 | .build* 2 | -------------------------------------------------------------------------------- /packages/telescope-update-prompt/lib/client/templates/update_banner.css: -------------------------------------------------------------------------------- 1 | .update-banner{ 2 | overflow: hidden; 3 | } 4 | .update-content{ 5 | float: left; 6 | } 7 | .update-version{ 8 | float: left; 9 | background: #DD3416; 10 | color: white; 11 | text-align: center; 12 | padding: 5px 10px; 13 | margin: 0px 15px 0px 0px; 14 | } 15 | .update-prompt{ 16 | font-weight: bold; 17 | line-height: 1; 18 | margin-bottom: 5px; 19 | } 20 | .update-message{ 21 | font-size: 14px; 22 | } -------------------------------------------------------------------------------- /packages/telescope-update-prompt/lib/client/templates/update_banner.html: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /packages/telescope-update-prompt/lib/client/templates/update_banner.js: -------------------------------------------------------------------------------- 1 | Template[getTemplate('updateBanner')].helpers({ 2 | showBanner: function () { 3 | return Session.get('updateVersion'); 4 | }, 5 | version: function () { 6 | return Session.get('updateVersion'); 7 | }, 8 | currentVersion: function () { 9 | return telescopeVersion; 10 | }, 11 | message: function () { 12 | return Session.get('updateMessage'); 13 | } 14 | }); -------------------------------------------------------------------------------- /packages/telescope-update-prompt/lib/server/phone_home.js: -------------------------------------------------------------------------------- 1 | Meteor.methods({ 2 | phoneHome: function () { 3 | 4 | return false; 5 | } 6 | }) 7 | -------------------------------------------------------------------------------- /packages/telescope-update-prompt/package.js: -------------------------------------------------------------------------------- 1 | Package.describe({ 2 | summary: "Telescope update prompt package.", 3 | version: '0.1.0', 4 | name: "telescope-update-prompt" 5 | }); 6 | 7 | Package.onUse(function (api) { 8 | 9 | api.use(['telescope-lib', 'telescope-base', 'http'], ['client', 'server']); 10 | 11 | api.use([ 12 | 'jquery', 13 | 'underscore', 14 | 'iron:router', 15 | 'templating' 16 | ], 'client'); 17 | 18 | 19 | api.add_files([ 20 | 'lib/client/update.js', 21 | 'lib/client/templates/update_banner.html', 22 | 'lib/client/templates/update_banner.js', 23 | 'lib/client/templates/update_banner.css' 24 | ], ['client']); 25 | 26 | api.add_files([ 27 | 'lib/server/phone_home.js' 28 | ], ['server']); 29 | 30 | api.export([ 31 | 'compareVersions' 32 | ]); 33 | }); -------------------------------------------------------------------------------- /project-tap.i18n: -------------------------------------------------------------------------------- 1 | { 2 | "helper_name": "_" 3 | } 4 | -------------------------------------------------------------------------------- /public/img/bg-black.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/public/img/bg-black.png -------------------------------------------------------------------------------- /public/img/bg-black@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/public/img/bg-black@2x.png -------------------------------------------------------------------------------- /public/img/bg-header.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/public/img/bg-header.png -------------------------------------------------------------------------------- /public/img/bg-header@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/public/img/bg-header@2x.png -------------------------------------------------------------------------------- /public/img/bg.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/public/img/bg.png -------------------------------------------------------------------------------- /public/img/bg@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/public/img/bg@2x.png -------------------------------------------------------------------------------- /public/img/default-avatar.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/public/img/default-avatar.png -------------------------------------------------------------------------------- /public/img/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/public/img/favicon.ico -------------------------------------------------------------------------------- /public/img/loading.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/public/img/loading.gif -------------------------------------------------------------------------------- /public/img/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/public/img/logo.png -------------------------------------------------------------------------------- /public/img/logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/public/img/logo@2x.png -------------------------------------------------------------------------------- /public/img/telescope-logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/public/img/telescope-logo.png -------------------------------------------------------------------------------- /public/img/telescope-logo2.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/public/img/telescope-logo2.png -------------------------------------------------------------------------------- /public/img/telescope-logo@2x.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/jparyani/Telescope/a291d716a16595d127f66f5064f4ae1a761051dd/public/img/telescope-logo@2x.png -------------------------------------------------------------------------------- /scss.json: -------------------------------------------------------------------------------- 1 | { 2 | "enableAutoprefixer": true, 3 | "outputStyle": "compressed", 4 | "sourceComments": true, 5 | "sourceMap": true 6 | } -------------------------------------------------------------------------------- /server/publications/posts_list.js: -------------------------------------------------------------------------------- 1 | // Publish a list of posts 2 | 3 | Meteor.publish('postsList', function(terms) { 4 | if(can.viewById(this.userId)){ 5 | var parameters = getPostsParameters(terms), 6 | posts = Posts.find(parameters.find, parameters.options); 7 | 8 | return posts; 9 | } 10 | return []; 11 | }); 12 | 13 | // Publish all the users that have posted the currently displayed list of posts 14 | // plus the commenters for each post 15 | 16 | Meteor.publish('postsListUsers', function(terms) { 17 | if(can.viewById(this.userId)){ 18 | var parameters = getPostsParameters(terms), 19 | posts = Posts.find(parameters.find, parameters.options), 20 | postsIds = _.pluck(posts.fetch(), '_id'), 21 | userIds = _.pluck(posts.fetch(), 'userId'); 22 | 23 | // for each post, add first four commenter's userIds to userIds array 24 | posts.forEach(function (post) { 25 | userIds = userIds.concat(_.first(post.commenters,4)); 26 | }); 27 | 28 | userIds = _.unique(userIds); 29 | 30 | return Meteor.users.find({_id: {$in: userIds}}, {fields: avatarOptions, multi: true}); 31 | } 32 | return []; 33 | }); 34 | -------------------------------------------------------------------------------- /server/publications/settings.js: -------------------------------------------------------------------------------- 1 | Meteor.publish('settings', function() { 2 | var options = {}; 3 | var privateFields = {}; 4 | 5 | // look at SettingsSchema to see which fields should be kept private 6 | _.each(SettingsSchema._schema, function( val, key ) { 7 | if (val.autoform && !!val.autoform.private) 8 | privateFields[key] = false; 9 | }); 10 | 11 | if(!isAdminById(this.userId)){ 12 | options = _.extend(options, { 13 | fields: privateFields 14 | }); 15 | } 16 | return Settings.find({}, options); 17 | }); -------------------------------------------------------------------------------- /server/publications/single_post.js: -------------------------------------------------------------------------------- 1 | // Publish a single post 2 | 3 | Meteor.publish('singlePost', function(id) { 4 | if (can.viewById(this.userId)){ 5 | return Posts.find(id); 6 | } 7 | return []; 8 | }); 9 | 10 | // Publish authors of the current post and its comments 11 | 12 | Meteor.publish('postUsers', function(postId) { 13 | if (can.viewById(this.userId)){ 14 | // publish post author and post commenters 15 | var post = Posts.findOne(postId), 16 | users = []; 17 | 18 | if (post) { 19 | var comments = Comments.find({postId: post._id}).fetch(); 20 | // get IDs from all commenters on the post, plus post author's ID 21 | users = _.pluck(comments, "userId"); 22 | users.push(post.userId); 23 | users = _.unique(users); 24 | } 25 | 26 | return Meteor.users.find({_id: {$in: users}}, {fields: privacyOptions}); 27 | } 28 | return []; 29 | }); 30 | 31 | // Publish comments for a specific post 32 | 33 | Meteor.publish('postComments', function(postId) { 34 | if (can.viewById(this.userId)){ 35 | return Comments.find({postId: postId}); 36 | } 37 | return []; 38 | }); -------------------------------------------------------------------------------- /server/publications/users.js: -------------------------------------------------------------------------------- 1 | // Publish the current user 2 | 3 | Meteor.publish('currentUser', function() { 4 | var user = Meteor.users.find({_id: this.userId}); 5 | return user; 6 | }); 7 | 8 | // publish all users for admins to make autocomplete work 9 | // TODO: find a better way 10 | 11 | Meteor.publish('allUsersAdmin', function() { 12 | var selector = getSetting('requirePostInvite') ? {isInvited: true} : {}; // only users that can post 13 | if (isAdminById(this.userId)) { 14 | return Meteor.users.find(selector, {fields: { 15 | _id: true, 16 | profile: true, 17 | slug: true 18 | }}); 19 | } 20 | return []; 21 | }); 22 | -------------------------------------------------------------------------------- /server/publications/users_dashboard.js: -------------------------------------------------------------------------------- 1 | // Publish all users 2 | 3 | Meteor.publish('allUsers', function(filterBy, sortBy, limit) { 4 | if(isAdminById(this.userId)){ 5 | var parameters = getUsersParameters(filterBy, sortBy, limit); 6 | return Meteor.users.find(parameters.find, parameters.options); 7 | } 8 | return []; 9 | }); 10 | -------------------------------------------------------------------------------- /server/start.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function () { 2 | logEvent({ 3 | name: "firstRun", 4 | unique: true, // will only get logged a single time 5 | important: true 6 | }) 7 | }); 8 | 9 | if (getSetting('mailUrl')) 10 | process.env.MAIL_URL = getSetting('mailUrl'); 11 | -------------------------------------------------------------------------------- /server/start_cron.js: -------------------------------------------------------------------------------- 1 | Meteor.startup(function() { 2 | SyncedCron.start(); 3 | }); 4 | -------------------------------------------------------------------------------- /server/testing.js: -------------------------------------------------------------------------------- 1 | var isTesting = Meteor.settings && Meteor.settings.isTesting; 2 | 3 | if (isTesting) { 4 | console.log('Adding login functions'); 5 | Meteor.methods({ 6 | // login from client with Meteor.call('loginTest', function(err, res) { Meteor.loginWithToken(res, function() {}); }) 7 | loginTest: function() { 8 | var login, token; 9 | Meteor.users.remove({}); 10 | login = Accounts.updateOrCreateUserFromExternalService("sandstorm", { 11 | id: 0, 12 | permissions: ['admin'] 13 | }, { 14 | profile: { 15 | name: 'Test Admin' 16 | } 17 | }); 18 | console.log(login); 19 | token = Accounts._generateStampedLoginToken(); 20 | Accounts._insertLoginToken(login.userId, token); 21 | return token.token; 22 | } 23 | }); 24 | } 25 | -------------------------------------------------------------------------------- /testing.settings.json: -------------------------------------------------------------------------------- 1 | {"isTesting" : true} 2 | --------------------------------------------------------------------------------