├── .DS_Store ├── .gitignore ├── Gemfile ├── Gemfile.lock ├── README.md ├── Rakefile ├── app ├── assets │ ├── images │ │ ├── .DS_Store │ │ ├── .keep │ │ ├── favicon1.ico │ │ └── large_logo.png │ ├── javascripts │ │ ├── application.js │ │ ├── collections │ │ │ ├── follows_collection.js │ │ │ ├── pub_collection.js │ │ │ ├── pub_edits_collection.js │ │ │ ├── pub_writes_collection.js │ │ │ ├── story_collection.js │ │ │ ├── taggings_collections.js │ │ │ ├── tags_collection.js │ │ │ └── user_collection.js │ │ ├── follows.js.coffee │ │ ├── large.js │ │ ├── models │ │ │ ├── feeds.js │ │ │ ├── follows.js │ │ │ ├── pub_edits.js │ │ │ ├── pub_writes.js │ │ │ ├── publications.js │ │ │ ├── stories.js │ │ │ ├── taggings.js │ │ │ ├── tags.js │ │ │ └── users.js │ │ ├── publication_edits.js.coffee │ │ ├── publication_writes.js.coffee │ │ ├── publications.coffee │ │ ├── routers │ │ │ ├── .keep │ │ │ ├── pubs_router.js │ │ │ ├── stories_router.js │ │ │ ├── tags_router.js │ │ │ └── users_router.js │ │ ├── sessions.coffee │ │ ├── stories.coffee │ │ ├── users.coffee │ │ ├── utils │ │ │ └── composite_view.js │ │ └── views │ │ │ ├── .keep │ │ │ ├── home_show.js │ │ │ ├── new_pub.js │ │ │ ├── new_story.js │ │ │ ├── new_story_preview.js │ │ │ ├── pub_about.js │ │ │ ├── pub_edit.js │ │ │ ├── pub_show.js │ │ │ ├── search_show.js │ │ │ ├── story_edit.js │ │ │ ├── story_preview.js │ │ │ ├── story_preview_search.js │ │ │ ├── story_show.js │ │ │ ├── tag_show.js │ │ │ ├── user_edit.js │ │ │ ├── user_show.js │ │ │ └── your_stories.js │ ├── stylesheets │ │ ├── application.css.scss │ │ ├── follows.css.scss │ │ ├── publication_edits.css.scss │ │ ├── publication_writes.css.scss │ │ ├── publications.scss │ │ ├── sessions.scss │ │ ├── stories.scss │ │ └── users.scss │ └── templates │ │ ├── feeds │ │ ├── _current_username.jst.ejs │ │ └── feed_show.jst.ejs │ │ ├── publications │ │ ├── new_pub.jst.ejs │ │ ├── pub_about.jst.ejs │ │ ├── pub_about_link.jst.ejs │ │ ├── pub_index.jst.ejs │ │ └── pub_show.jst.ejs │ │ ├── search │ │ └── search_show.jst.ejs │ │ ├── stories │ │ ├── _author_username.jst.ejs │ │ ├── _edit_and_delete_buttons.jst.ejs │ │ ├── _in_response_link.jst.ejs │ │ ├── _insert_toolbar.jst.ejs │ │ ├── _new_story_header.jst.ejs │ │ ├── new_story.jst.ejs │ │ ├── new_story_preview.jst.ejs │ │ ├── story_preview.jst.ejs │ │ ├── story_preview_search.jst.ejs │ │ ├── story_show.jst.ejs │ │ └── your_stories.jst.ejs │ │ ├── tags │ │ └── tag_show.jst.ejs │ │ └── users │ │ ├── user_edit.jst.ejs │ │ ├── user_edit_toggle.jst.ejs │ │ ├── user_index.jst.ejs │ │ └── user_show.jst.ejs ├── controllers │ ├── api │ │ ├── api_controller.rb │ │ ├── follows_controller.rb │ │ ├── publication_edits_controller.rb │ │ ├── publication_writes_controller.rb │ │ ├── publications_controller.rb │ │ ├── search_controller.rb │ │ ├── stories_controller.rb │ │ ├── taggings_controller.rb │ │ ├── tags_controller.rb │ │ └── users_controller.rb │ ├── application_controller.rb │ ├── concerns │ │ └── .keep │ ├── sessions_controller.rb │ ├── static_pages_controller.rb │ └── users_controller.rb ├── helpers │ ├── application_helper.rb │ ├── follows_helper.rb │ ├── publication_edits_helper.rb │ ├── publication_writes_helper.rb │ ├── publications_helper.rb │ ├── sessions_helper.rb │ ├── stories_helper.rb │ └── users_helper.rb ├── mailers │ └── .keep ├── models │ ├── .keep │ ├── concerns │ │ ├── .keep │ │ ├── followable.rb │ │ └── taggable.rb │ ├── follow.rb │ ├── publication.rb │ ├── publication_edit.rb │ ├── publication_write.rb │ ├── story.rb │ ├── tag.rb │ ├── tagging.rb │ └── user.rb └── views │ ├── api │ ├── follows │ │ ├── _follow.json.jbuilder │ │ └── show.json.jbuilder │ ├── pub_edits │ │ ├── _pubedit.json.jbuilder │ │ └── show.json.jbuilder │ ├── pub_writes │ │ ├── _pubwrite.json.jbuilder │ │ └── show.json.jbuilder │ ├── publications │ │ ├── .keep │ │ ├── _pub.json.jbuilder │ │ └── show.json.jbuilder │ ├── stories │ │ ├── .keep │ │ ├── _story.json.jbuilder │ │ ├── index.json.jbuilder │ │ └── show.json.jbuilder │ ├── taggings │ │ ├── _tagging.json.jbuilder │ │ └── show.json.jbuilder │ ├── tags │ │ ├── _tag.json.jbuilder │ │ └── show.json.jbuilder │ └── users │ │ ├── .keep │ │ ├── _user.json.jbuilder │ │ └── show.json.jbuilder │ ├── layouts │ ├── _header.html.erb │ └── application.html.erb │ ├── sessions │ └── new.html.erb │ ├── static_pages │ └── root.html.erb │ └── users │ └── new.html.erb ├── bin ├── bundle ├── rails ├── rake ├── setup └── spring ├── config.ru ├── config ├── application.rb ├── boot.rb ├── database.yml ├── environment.rb ├── environments │ ├── development.rb │ ├── production.rb │ └── test.rb ├── initializers │ ├── assets.rb │ ├── backtrace_silencers.rb │ ├── cookies_serializer.rb │ ├── filter_parameter_logging.rb │ ├── inflections.rb │ ├── mime_types.rb │ ├── session_store.rb │ └── wrap_parameters.rb ├── locales │ └── en.yml ├── routes.rb ├── secrets.yml └── storage.yml ├── db ├── migrate │ ├── 20150407030922_create_publications.rb │ ├── 20150407031014_create_users.rb │ ├── 20150407031117_create_stories.rb │ ├── 20150407031152_create_tags.rb │ ├── 20150407210923_remove_null_false_from_pub_id.rb │ ├── 20150407232751_add_description_to_users.rb │ ├── 20150408182531_create_follows.rb │ ├── 20150409212038_add_header_image_to_stories.rb │ ├── 20150409224359_add_header_image_to_pubs.rb │ ├── 20150411074919_create_publication_edits.rb │ ├── 20150411075008_create_publication_writes.rb │ ├── 20150412011132_create_taggings.rb │ ├── 20150413001413_change_pub_edits_table.rb │ ├── 20150415081536_make_title_null_allowed.rb │ ├── 20150415184559_add_headers_and_icons.rb │ ├── 20150417185017_header_align_column.rb │ ├── 20150417185247_default_align_value.rb │ ├── 20150417191221_remove_default_value.rb │ └── 20150417192443_replace_header_align_column.rb ├── schema.rb └── seeds.rb ├── docs ├── phases │ ├── phase1.md │ ├── phase2.md │ ├── phase3.md │ ├── phase4.md │ └── phase5.md ├── schema.md ├── views.md └── wireframes │ ├── .DS_Store │ ├── LP_signed_in.png │ ├── LP_signed_out.png │ ├── confirm_publish.png │ ├── new_session.png │ ├── pub_about.png │ ├── pub_form.png │ ├── pub_show.png │ ├── search_results.png │ ├── story_form.png │ ├── story_show.png │ ├── user_show.png │ └── user_stories.png ├── lib ├── assets │ └── .keep └── tasks │ ├── .keep │ └── delete_everything.rake ├── log └── .keep ├── npm-debug.log ├── public ├── 404.html ├── 422.html ├── 500.html ├── favicon.ico └── robots.txt ├── test ├── controllers │ ├── .keep │ ├── follows_controller_test.rb │ ├── publication_edits_controller_test.rb │ ├── publication_writes_controller_test.rb │ ├── publications_controller_test.rb │ ├── sessions_controller_test.rb │ ├── stories_controller_test.rb │ └── users_controller_test.rb ├── fixtures │ ├── .keep │ ├── follows.yml │ ├── publication_edits.yml │ ├── publication_writes.yml │ ├── publications.yml │ ├── stories.yml │ ├── taggings.yml │ ├── tags.yml │ └── users.yml ├── helpers │ └── .keep ├── integration │ └── .keep ├── mailers │ └── .keep ├── models │ ├── .keep │ ├── follow_test.rb │ ├── publication_edit_test.rb │ ├── publication_test.rb │ ├── publication_write_test.rb │ ├── story_test.rb │ ├── tag_test.rb │ ├── tagging_test.rb │ └── user_test.rb └── test_helper.rb └── vendor └── assets ├── javascripts ├── .DS_Store ├── .keep ├── jquery.timeago.js ├── medium-editor.js ├── selectivity-full.js └── serializeJSON.js └── stylesheets ├── .keep ├── medium-editor.css ├── selectivity-full.css └── themes ├── bootstrap.css ├── bootstrap.min.css ├── default.css ├── default.min.css ├── flat.css ├── flat.min.css ├── mani.css ├── mani.min.css ├── roman.css └── roman.min.css /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/.DS_Store -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # See https://help.github.com/articles/ignoring-files for more about ignoring files. 2 | # 3 | # If you find yourself ignoring temporary files generated by your text editor 4 | # or operating system, you probably want to add a global ignore instead: 5 | # git config --global core.excludesfile '~/.gitignore_global' 6 | 7 | # Ignore bundler config. 8 | /.bundle 9 | 10 | # Ignore all logfiles and tempfiles. 11 | /log/* 12 | !/log/.keep 13 | /tmp 14 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | ruby '3.1.2' 3 | 4 | gem 'actionpack', '~> 7.0.3' 5 | gem 'activemodel', '~> 7.0.3' 6 | gem 'activesupport', '~> 7.0.3' 7 | gem 'rails-backbone' 8 | gem 'bcrypt' 9 | gem 'bootstrap-sass' 10 | gem 'coffee-rails', '>= 4.1.0' 11 | gem 'font-awesome-sass', '~> 4.4.0' 12 | gem 'jquery-rails' 13 | gem 'jquery-ui-rails' 14 | gem 'jbuilder', '~> 2.11.5' 15 | gem 'rails', '7.0.3' 16 | gem 'railties', "~> 7.0.3" 17 | gem 'sass-rails', '~> 5.0' 18 | gem 'pg' 19 | gem 'uglifier', '>= 1.3.0' 20 | gem 'newrelic_rpm' 21 | gem 'webrick', '~> 1.7' 22 | 23 | group :development, :test do 24 | gem 'byebug' 25 | gem 'web-console', '>= 3.3.0' 26 | gem 'spring' 27 | end 28 | 29 | group :development do 30 | gem 'better_errors' 31 | gem 'binding_of_caller' 32 | gem 'pry-rails' 33 | end 34 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require File.expand_path('../config/application', __FILE__) 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /app/assets/images/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/app/assets/images/.DS_Store -------------------------------------------------------------------------------- /app/assets/images/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/app/assets/images/.keep -------------------------------------------------------------------------------- /app/assets/images/favicon1.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/app/assets/images/favicon1.ico -------------------------------------------------------------------------------- /app/assets/images/large_logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/app/assets/images/large_logo.png -------------------------------------------------------------------------------- /app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, 5 | // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // compiled file. 9 | // 10 | // Read Sprockets README (https://github.com/sstephenson/sprockets#sprockets-directives) for details 11 | // about supported directives. 12 | // 13 | //= require jquery 14 | //= require jquery-ui 15 | //= require jquery_ujs 16 | //= require selectivity-full 17 | //= require underscore 18 | //= require backbone 19 | //= require serializeJSON 20 | //= require jquery.timeago 21 | //= require medium-editor 22 | //= require bootstrap 23 | //= require large 24 | //= require_tree ../templates 25 | //= require_tree ./utils 26 | //= require_tree ./models 27 | //= require_tree ./collections 28 | //= require_tree ./views 29 | //= require_tree ./routers 30 | //= require_tree . 31 | -------------------------------------------------------------------------------- /app/assets/javascripts/collections/follows_collection.js: -------------------------------------------------------------------------------- 1 | Large.Collections.Follows = Backbone.Collection.extend({ 2 | url: '/api/follows', 3 | model: Large.Models.Follow, 4 | 5 | }); 6 | -------------------------------------------------------------------------------- /app/assets/javascripts/collections/pub_collection.js: -------------------------------------------------------------------------------- 1 | Large.Collections.Publications = Backbone.Collection.extend({ 2 | url: 'api/publications', 3 | model: Large.Models.Publication, 4 | 5 | getOrFetch: function (id) { 6 | var model = this.get(id); 7 | if (model === undefined) { 8 | model = new Large.Models.Publication({ id: id }); 9 | model.fetch({ 10 | success: function () { 11 | this.add(model); 12 | }.bind(this) 13 | }); 14 | } else { 15 | model.fetch(); 16 | } 17 | return model; 18 | } 19 | }); 20 | -------------------------------------------------------------------------------- /app/assets/javascripts/collections/pub_edits_collection.js: -------------------------------------------------------------------------------- 1 | Large.Collections.PubEdits = Backbone.Collection.extend({ 2 | url: 'api/publication_edits', 3 | model: Large.Models.PubEdit 4 | }) 5 | -------------------------------------------------------------------------------- /app/assets/javascripts/collections/pub_writes_collection.js: -------------------------------------------------------------------------------- 1 | Large.Collections.PubWrites = Backbone.Collection.extend({ 2 | url: 'api/publication_writes', 3 | model: Large.Models.PubWrite 4 | }) 5 | -------------------------------------------------------------------------------- /app/assets/javascripts/collections/story_collection.js: -------------------------------------------------------------------------------- 1 | Large.Collections.Stories = Backbone.Collection.extend({ 2 | url: 'api/stories', 3 | model: Large.Models.Story, 4 | 5 | comparator: function (story) { 6 | return story.get('created_at'); 7 | }, 8 | 9 | getOrFetch: function (id) { 10 | var model = this.get(id); 11 | if (model === undefined) { 12 | model = new Large.Models.Story({ id: id }); 13 | model.fetch({ 14 | success: function () { 15 | this.add(model); 16 | }.bind(this) 17 | }); 18 | } else { 19 | model.fetch(); 20 | } 21 | return model; 22 | }, 23 | 24 | parse: function (payload) { 25 | return payload; 26 | } 27 | }); 28 | -------------------------------------------------------------------------------- /app/assets/javascripts/collections/taggings_collections.js: -------------------------------------------------------------------------------- 1 | Large.Collections.Taggings = Backbone.Collection.extend({ 2 | url: 'api/taggings', 3 | model: Large.Models.Tagging, 4 | 5 | getOrFetch: function (id) { 6 | var model = this.get(id); 7 | if (model === undefined) { 8 | model = new Large.Models.Tagging({ id: id }); 9 | model.fetch({ 10 | success: function () { 11 | this.add(model); 12 | }.bind(this) 13 | }); 14 | } else { 15 | model.fetch(); 16 | } 17 | return model; 18 | } 19 | }); 20 | -------------------------------------------------------------------------------- /app/assets/javascripts/collections/tags_collection.js: -------------------------------------------------------------------------------- 1 | Large.Collections.Tags = Backbone.Collection.extend({ 2 | url: 'api/tags', 3 | model: Large.Models.Tag, 4 | 5 | getOrFetch: function (id) { 6 | var model = this.get(id); 7 | if (model === undefined) { 8 | model = new Large.Models.Tag({ id: id }); 9 | model.fetch({ 10 | success: function () { 11 | this.add(model); 12 | }.bind(this) 13 | }); 14 | } else { 15 | model.fetch(); 16 | } 17 | return model; 18 | } 19 | }); 20 | -------------------------------------------------------------------------------- /app/assets/javascripts/collections/user_collection.js: -------------------------------------------------------------------------------- 1 | Large.Collections.Users = Backbone.Collection.extend({ 2 | url: 'api/users', 3 | model: Large.Models.User, 4 | 5 | getOrFetch: function (id) { 6 | var model = this.get(id); 7 | if (model === undefined) { 8 | model = new Large.Models.User({ id: id }); 9 | model.fetch({ 10 | success: function () { 11 | this.add(model); 12 | }.bind(this) 13 | }); 14 | } else { 15 | model.fetch(); 16 | } 17 | return model; 18 | } 19 | }); 20 | -------------------------------------------------------------------------------- /app/assets/javascripts/follows.js.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/large.js: -------------------------------------------------------------------------------- 1 | window.Large = { 2 | Models: {}, 3 | Collections: {}, 4 | Views: {}, 5 | Routers: {}, 6 | initialize: function() { 7 | // this.NAV_VIEW = new Large.Views.NavShow({ 8 | // el: $('nav') 9 | // }); 10 | 11 | Large.Collections.users = new Large.Collections.Users(); 12 | Large.Collections.users.fetch(); 13 | Large.Collections.publications = new Large.Collections.Publications(); 14 | Large.Collections.stories = new Large.Collections.Stories(); 15 | Large.Collections.follows = new Large.Collections.Follows(); 16 | Large.Collections.ttags = new Large.Collections.Tags(); 17 | 18 | new Large.Routers.UsersRouter({content: $('#content')}); 19 | new Large.Routers.StoriesRouter({content: $('#content')}); 20 | new Large.Routers.PubsRouter({content: $('#content')}); 21 | new Large.Routers.TagsRouter({content: $('#content')}); 22 | 23 | Backbone.history.start(); 24 | } 25 | }; 26 | -------------------------------------------------------------------------------- /app/assets/javascripts/models/feeds.js: -------------------------------------------------------------------------------- 1 | Large.Models.Feed = Backbone.Model.extend({ 2 | 3 | }); 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/models/follows.js: -------------------------------------------------------------------------------- 1 | Large.Models.Follow = Backbone.Model.extend({ 2 | urlRoot: '/api/follows' 3 | }); 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/models/pub_edits.js: -------------------------------------------------------------------------------- 1 | Large.Models.PubEdit = Backbone.Model.extend({ 2 | urlRoot: 'api/publication_edits' 3 | }) 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/models/pub_writes.js: -------------------------------------------------------------------------------- 1 | Large.Models.PubWrite = Backbone.Model.extend({ 2 | urlRoot: 'api/publication_writes' 3 | }) 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/models/publications.js: -------------------------------------------------------------------------------- 1 | Large.Models.Publication = Backbone.Model.extend({ 2 | urlRoot: 'api/publications', 3 | 4 | ttags: function () { 5 | if (this._tags === undefined) { 6 | this._tags = new Large.Collections.Tags([]); 7 | } 8 | return this._tags 9 | }, 10 | 11 | taggings: function () { 12 | if (this._taggings === undefined) { 13 | this._taggings = new Large.Collections.Taggings([], 14 | { taggable_id: this.id, taggable_type: "Publication"}); 15 | } 16 | return this._taggings; 17 | }, 18 | 19 | followers: function () { 20 | if (this._followers === undefined) { 21 | this._followers = new Large.Collections.Users([]) 22 | } 23 | return this._followers; 24 | }, 25 | 26 | follows: function () { 27 | if (this._follows === undefined) { 28 | this._follows = new Large.Collections.Follows([], 29 | { followable_id: this.id, followable_type: "Publication"}); 30 | } 31 | return this._follows; 32 | }, 33 | 34 | stories: function () { 35 | if (this._stories === undefined) { 36 | this._stories = new Large.Collections.Stories([], { 37 | pub_id: this.id, publication: this 38 | }); 39 | } 40 | return this._stories; 41 | }, 42 | 43 | pubWrites: function () { 44 | if (this._pubWrites === undefined) { 45 | this._pubWrites = new Large.Collections.PubWrites([], { 46 | pub_id: this.id 47 | }) 48 | } 49 | return this._pubWrites 50 | }, 51 | 52 | pubEdits: function () { 53 | if (this._pubEdits === undefined) { 54 | this._pubEdits = new Large.Collections.PubEdits([], { 55 | pub_id: this.id 56 | }) 57 | } 58 | return this._pubEdits 59 | }, 60 | 61 | writers: function () { 62 | if (this._writers === undefined) { 63 | this._writers = new Large.Collections.Users([]) 64 | } 65 | return this._writers 66 | }, 67 | 68 | editors: function () { 69 | if (this._editors === undefined) { 70 | this._editors = new Large.Collections.Users([]) 71 | } 72 | return this._editors 73 | }, 74 | 75 | parse: function (payload) { 76 | // debugger 77 | if (payload.stories) { 78 | this.stories().set(payload.stories, { parse: true }); 79 | delete payload.stories 80 | } 81 | 82 | if (payload.follows) { 83 | this.follows().set(payload.follows, { parse: true }); 84 | delete payload.follows 85 | } 86 | 87 | if (payload.pub_edits) { 88 | this.pubEdits().set(payload.pub_edits, { parse: true }); 89 | delete payload.pub_edits 90 | } 91 | 92 | if (payload.pub_writes) { 93 | this.pubWrites().set(payload.pub_writes, { parse: true }); 94 | delete payload.pub_writes 95 | } 96 | 97 | if (payload.writers) { 98 | this.writers().set(payload.writers, { parse: true }); 99 | delete payload.writers 100 | } 101 | 102 | if (payload.editors) { 103 | this.editors().set(payload.editors, { parse: true }); 104 | delete payload.editors 105 | } 106 | 107 | if (payload.followers) { 108 | this.followers().set(payload.followers, { parse: true }); 109 | delete payload.followers; 110 | } 111 | 112 | if (payload.taggings) { 113 | this.taggings().set(payload.taggings, { parse: true }); 114 | delete payload.taggings 115 | } 116 | 117 | if (payload.tags) { 118 | this.ttags().set(payload.tags, { parse: true }); 119 | delete payload.tags 120 | } 121 | 122 | return payload; 123 | } 124 | 125 | }); 126 | -------------------------------------------------------------------------------- /app/assets/javascripts/models/stories.js: -------------------------------------------------------------------------------- 1 | Large.Models.Story = Backbone.Model.extend({ 2 | urlRoot: 'api/stories', 3 | 4 | ttags: function () { 5 | if (this._ttags === undefined) { 6 | this._ttags = new Large.Collections.Tags([]); 7 | } 8 | return this._ttags 9 | }, 10 | 11 | taggings: function () { 12 | if (this._taggings === undefined) { 13 | this._taggings = new Large.Collections.Taggings([], 14 | { taggable_id: this.id, taggable_type: "Story"}); 15 | } 16 | return this._taggings; 17 | }, 18 | 19 | parse: function (payload) { 20 | // debugger 21 | if (payload.taggings) { 22 | this.taggings().set(payload.taggings, { parse: true }); 23 | delete payload.taggings 24 | } 25 | 26 | if (payload.tags) { 27 | this.ttags().set(payload.tags, { parse: true }); 28 | delete payload.tags 29 | } 30 | 31 | return payload; 32 | } 33 | }); 34 | -------------------------------------------------------------------------------- /app/assets/javascripts/models/taggings.js: -------------------------------------------------------------------------------- 1 | Large.Models.Tagging = Backbone.Model.extend({ 2 | urlRoot: 'api/taggings' 3 | }) 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/models/tags.js: -------------------------------------------------------------------------------- 1 | Large.Models.Tag = Backbone.Model.extend({ 2 | urlRoot: "api/tags", 3 | 4 | taggings: function () { 5 | if (this._taggings === undefined) { 6 | this._taggings = new Large.Collections.Taggings([]); 7 | } 8 | return this._taggings; 9 | }, 10 | 11 | taggedStories: function () { 12 | if (this._taggedStories === undefined) { 13 | this._taggedStories = new Large.Collections.Stories([]); 14 | } 15 | return this._taggedStories; 16 | }, 17 | 18 | taggedPubs: function () { 19 | if (this._taggedPubs === undefined) { 20 | this._taggedPubs = new Large.Collections.Publications([]); 21 | } 22 | return this._taggedPubs; 23 | }, 24 | 25 | parse: function (payload) { 26 | if (payload.taggings) { 27 | this.taggings().set(payload.taggings, { parse: true }); 28 | delete payload.taggings 29 | } 30 | 31 | if (payload.tagged_stories) { 32 | this.taggedStories().set(payload.tagged_stories, { parse: true }); 33 | delete payload.tagged_stories 34 | } 35 | 36 | if (payload.tagged_pubs) { 37 | this.taggedPubs().set(payload.tagged_pubs, { parse: true }); 38 | delete payload.tagged_pubs 39 | } 40 | return payload 41 | } 42 | }); 43 | -------------------------------------------------------------------------------- /app/assets/javascripts/models/users.js: -------------------------------------------------------------------------------- 1 | Large.Models.User = Backbone.Model.extend({ 2 | urlRoot: 'api/users', 3 | 4 | currentUser: function () { 5 | if (this._currentUser === undefined) { 6 | this._currentUser = new Large.Models.User(); 7 | } 8 | return this._currentUser; 9 | }, 10 | 11 | followers: function () { 12 | if (this._followers === undefined) { 13 | this._followers = new Large.Collections.Users([]) 14 | } 15 | return this._followers; 16 | }, 17 | 18 | followedUsers: function () { 19 | if (this._followedUsers === undefined) { 20 | this._followedUsers = new Large.Collections.Users([]) 21 | } 22 | return this._followedUsers; 23 | }, 24 | 25 | follows: function () { 26 | if (this._follows === undefined) { 27 | this._follows = new Large.Collections.Follows([], 28 | { followable_id: this.id, followable_type: "User" }); 29 | } 30 | return this._follows; 31 | }, 32 | 33 | followings: function () { 34 | if (this._followings === undefined) { 35 | this._followings = new Large.Collections.Follows([], 36 | { follower_id: this.id }); 37 | } 38 | return this._followings; 39 | }, 40 | 41 | stories: function () { 42 | if (this._stories === undefined) { 43 | this._stories = new Large.Collections.Stories([], { 44 | author_id: this.id, author: this 45 | }); 46 | } 47 | return this._stories; 48 | }, 49 | 50 | pubs: function () { 51 | if (this._pubs === undefined) { 52 | this._pubs = new Large.Collections.Publications([], { 53 | owner_id: this.id, owner: this 54 | }); 55 | } 56 | return this._pubs; 57 | }, 58 | 59 | contributedPubs: function () { 60 | if (this._contributedPubs === undefined) { 61 | this._contributedPubs = new Large.Collections.Publications([]); 62 | } 63 | return this._contributedPubs; 64 | }, 65 | 66 | editedPubs: function () { 67 | if (this._editedPubs === undefined) { 68 | this._editedPubs = new Large.Collections.Publications([]); 69 | } 70 | return this._editedPubs; 71 | }, 72 | 73 | parse: function (payload) { 74 | if (payload.stories) { 75 | this.stories().set(payload.stories, { parse: true }); 76 | delete payload.stories; 77 | } 78 | 79 | if (payload.publications) { 80 | this.pubs().set(payload.publications, { parse: true }); 81 | delete payload.publications; 82 | } 83 | 84 | if (payload.follows) { 85 | this.follows().set(payload.follows, { parse: true }); 86 | delete payload.follows; 87 | } 88 | 89 | if (payload.followings) { 90 | this.followings().set(payload.followings, { parse: true }); 91 | delete payload.followings; 92 | } 93 | 94 | if (payload.contributed_pubs) { 95 | this.contributedPubs().set(payload.contributed_pubs, { parse: true }); 96 | delete payload.contributed_pubs; 97 | } 98 | 99 | if (payload.edited_pubs) { 100 | this.editedPubs().set(payload.edited_pubs, { parse: true }); 101 | delete payload.edited_pubs; 102 | } 103 | 104 | if (payload.followers) { 105 | this.followers().set(payload.followers, { parse: true }); 106 | delete payload.followers; 107 | } 108 | 109 | if (payload.followed_users) { 110 | this.followedUsers().set(payload.followed_users, { parse: true }); 111 | delete payload.followed_users; 112 | } 113 | 114 | if (payload.current_user) { 115 | this.currentUser().set(payload.current_user, { parse: true }); 116 | delete payload.current_user; 117 | } 118 | 119 | return payload; 120 | } 121 | 122 | }); 123 | -------------------------------------------------------------------------------- /app/assets/javascripts/publication_edits.js.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/publication_writes.js.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/publications.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/routers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/app/assets/javascripts/routers/.keep -------------------------------------------------------------------------------- /app/assets/javascripts/routers/pubs_router.js: -------------------------------------------------------------------------------- 1 | Large.Routers.PubsRouter = Backbone.Router.extend({ 2 | routes: { 3 | "publications/new": "newPub", 4 | "publications/:id": "showPub", 5 | "publications/:id/edit": "editPub", 6 | "publications/:id/about": "aboutPub" 7 | }, 8 | 9 | initialize: function (options) { 10 | this.collection = new Large.Collections.Publications(); 11 | this.$rootEl = options.content; 12 | }, 13 | 14 | newPub: function () { 15 | Large.Collections.users.fetch(); 16 | Large.Collections.ttags.fetch(); 17 | var publication = new Large.Models.Publication(); 18 | var pubNew = new Large.Views.NewPub({ 19 | collection: this.collection, 20 | model: publication, 21 | users: Large.Collections.users, 22 | ttags: Large.Collections.ttags 23 | }); 24 | this._swapView(pubNew); 25 | }, 26 | 27 | showPub: function (id) { 28 | var pub = this.collection.getOrFetch(id); 29 | Large.Collections.users.fetch(); 30 | Large.Collections.follows.fetch({ 31 | data: { current_user: true } 32 | }); 33 | var showPub = new Large.Views.PubShow({ 34 | pub: pub, 35 | publications: this.collection, 36 | follows: Large.Collections.follows, 37 | allUsers: Large.Collections.users 38 | }); 39 | this._swapView(showPub); 40 | }, 41 | 42 | editPub: function (id) { 43 | var pub = this.collection.getOrFetch(id); 44 | var editPub = new Large.Views.PubEdit({ pub: pub }); 45 | this._swapView(editPub); 46 | }, 47 | 48 | aboutPub: function (id) { 49 | Large.Collections.follows.fetch({ 50 | data: { current_user: true } 51 | }); 52 | var pub = this.collection.getOrFetch(id); 53 | var aboutPub = new Large.Views.PubAbout({ 54 | pub: pub, 55 | follows: Large.Collections.follows 56 | }); 57 | this._swapView(aboutPub); 58 | }, 59 | 60 | _swapView: function (view) { 61 | this._currentView && this._currentView.remove(); 62 | this._currentView = view; 63 | this.$rootEl.html(view.$el); 64 | view.render(); 65 | } 66 | }); 67 | -------------------------------------------------------------------------------- /app/assets/javascripts/routers/tags_router.js: -------------------------------------------------------------------------------- 1 | Large.Routers.TagsRouter = Backbone.Router.extend({ 2 | routes: { 3 | "tags/:id": "tagShow" 4 | }, 5 | 6 | initialize: function (options) { 7 | this.collection = new Large.Collections.Tags(); 8 | this.$rootEl = options.content; 9 | }, 10 | 11 | tagShow: function (id) { 12 | var tag = this.collection.getOrFetch(id); 13 | Large.Collections.users.fetch(); 14 | Large.Collections.publications.fetch(); 15 | Large.Collections.ttags.fetch({ 16 | data: { tag_id: id } 17 | }) 18 | showTag = new Large.Views.TagShow({ 19 | ttag: tag, 20 | pubs: Large.Collections.publications, 21 | ttags: Large.Collections.ttags, 22 | users: Large.Collections.users, 23 | }); 24 | this._swapView(showTag); 25 | }, 26 | 27 | _swapView: function (view) { 28 | this._currentView && this._currentView.remove(); 29 | this._currentView = view; 30 | this.$rootEl.html(view.render().$el); 31 | } 32 | }); 33 | -------------------------------------------------------------------------------- /app/assets/javascripts/routers/users_router.js: -------------------------------------------------------------------------------- 1 | Large.Routers.UsersRouter = Backbone.Router.extend({ 2 | routes: { 3 | "users/:id": "userShow", 4 | "users/:id/edit": "userEdit" 5 | // "users/:id/your_stories": "yourStories" 6 | }, 7 | 8 | initialize: function (options) { 9 | Large.Collections.users.fetch(); 10 | this.$rootEl = options.content; 11 | }, 12 | 13 | userShow: function (id) { 14 | Large.Collections.publications.fetch(); 15 | Large.Collections.follows.fetch({ 16 | data: { current_user: true } 17 | }); 18 | 19 | var user = Large.Collections.users.getOrFetch(id); 20 | Large.Collections.users.fetch({ 21 | data: { current_user: true } 22 | }); 23 | Large.Collections.stories.fetch(); 24 | var showUser = new Large.Views.UserShow({ 25 | user: user, 26 | currentUser: Large.Collections.users, 27 | publications: Large.Collections.publications, 28 | follows: Large.Collections.follows, 29 | allStories: Large.Collections.stories 30 | }); 31 | this._swapView(showUser); 32 | }, 33 | 34 | userEdit: function (id) { 35 | Large.Collections.publications.fetch({ 36 | data: { current_user: false } 37 | }); 38 | Large.Collections.follows.fetch({ 39 | data: { current_user: true } 40 | }); 41 | 42 | var user = Large.Collections.users.getOrFetch(id); 43 | var editUser = new Large.Views.UserEdit({ 44 | user: user, 45 | publications: Large.Collections.publications, 46 | follows: Large.Collections.follows 47 | }); 48 | this._swapView(editUser); 49 | }, 50 | 51 | // yourStories: function () { 52 | // Large.Collections.publications.fetch({ 53 | // data: { current_user: true } 54 | // }); 55 | // Large.Collections.users.fetch({ 56 | // data: { current_user: true } 57 | // }); 58 | // var yourStoriesView = new Large.Views.YourStories({ 59 | // user: Large.Collections.users, 60 | // publications: Large.Collections.publications 61 | // }) 62 | // this._swapView(yourStoriesView); 63 | // }, 64 | 65 | _swapView: function (view) { 66 | this._currentView && this._currentView.remove(); 67 | this._currentView = view; 68 | this.$rootEl.html(view.render().$el); 69 | } 70 | 71 | }); 72 | -------------------------------------------------------------------------------- /app/assets/javascripts/sessions.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/stories.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/users.coffee: -------------------------------------------------------------------------------- 1 | # Place all the behaviors and hooks related to the matching controller here. 2 | # All this logic will automatically be available in application.js. 3 | # You can use CoffeeScript in this file: http://coffeescript.org/ 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/utils/composite_view.js: -------------------------------------------------------------------------------- 1 | Backbone.CompositeView = Backbone.View.extend({ 2 | addSubview: function (selector, subview) { 3 | this.subviews(selector).push(subview); 4 | // Try to attach the subview. Render it as a convenience. 5 | this.attachSubview(selector, subview.render()); 6 | }, 7 | 8 | attachSubview: function (selector, subview) { 9 | this.$(selector).prepend(subview.$el); 10 | // Bind events in case `subview` has previously been removed from 11 | // DOM. 12 | subview.delegateEvents(); 13 | 14 | if (subview.attachSubviews) { 15 | subview.attachSubviews(); 16 | } 17 | }, 18 | 19 | attachSubviews: function () { 20 | // I decided I didn't want a function that renders ALL the 21 | // subviews together. Instead, I think: 22 | // 23 | // * The user of CompositeView should explicitly render the 24 | // subview themself when they build the subview object. 25 | // * The subview should listenTo relevant events and re-render 26 | // itself. 27 | // 28 | // All that is necessary is "attaching" the subview `$el`s to the 29 | // relevant points in the parent CompositeView. 30 | 31 | var view = this; 32 | _(this.subviews()).each(function (subviews, selector) { 33 | view.$(selector).empty(); 34 | _(subviews).each(function (subview) { 35 | view.attachSubview(selector, subview); 36 | }); 37 | }); 38 | }, 39 | 40 | remove: function () { 41 | Backbone.View.prototype.remove.call(this); 42 | _(this.subviews()).each(function (subviews) { 43 | _(subviews).each(function (subview) { 44 | subview.remove(); 45 | }); 46 | }); 47 | }, 48 | 49 | removeSubview: function (selector, subview) { 50 | subview.remove(); 51 | 52 | var subviews = this.subviews(selector); 53 | subviews.splice(subviews.indexOf(subview), 1); 54 | }, 55 | 56 | subviews: function (selector) { 57 | // Map of selectors to subviews that live inside that selector. 58 | // Optionally pass a selector and I'll initialize/return an array 59 | // of subviews for the sel. 60 | this._subviews = this._subviews || {}; 61 | 62 | if (!selector) { 63 | return this._subviews; 64 | } else { 65 | this._subviews[selector] = this._subviews[selector] || []; 66 | return this._subviews[selector]; 67 | } 68 | } 69 | }); 70 | -------------------------------------------------------------------------------- /app/assets/javascripts/views/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/app/assets/javascripts/views/.keep -------------------------------------------------------------------------------- /app/assets/javascripts/views/home_show.js: -------------------------------------------------------------------------------- 1 | Large.Views.HomeShow = Backbone.CompositeView.extend({ 2 | template: JST['feeds/feed_show'], 3 | currentUsername: JST['feeds/_current_username'], 4 | 5 | events: { 6 | "click .pre-click": "showNewStory", 7 | "click #close-new": "hideNewStory", 8 | "mouseenter .sidebar": "handleEnter", 9 | "mouseleave .sidebar": "handleLeave" 10 | }, 11 | 12 | initialize: function (options) { 13 | this.stories = options.stories; 14 | this.publications = options.publications; 15 | this.ttags = options.ttags; 16 | this.hovering = false; 17 | // this.currentUser = options.currentUser; 18 | this.listenTo(this.ttags, 'sync', this.render); 19 | this.listenTo(this.stories, 'sync', this.render); 20 | $(window).scroll(this.scrollSidebar.bind(this)); 21 | 22 | this.stories.each(this.addStoryView.bind(this)); 23 | this.listenTo(this.stories, 'add', this.addStoryView); 24 | this.listenTo(this.stories, 'remove', this.removeStoryView); 25 | }, 26 | 27 | addStoryView: function (story) { 28 | var storyPreview = new Large.Views.StoryPreview({ 29 | model: story, 30 | publications: this.publications, 31 | stories: this.stories 32 | }); 33 | this.addSubview('.main-stories', storyPreview); 34 | }, 35 | 36 | removeStoryView: function (story) { 37 | var subviews = this.subviews('ul'); 38 | var i = _(subviews).findIndex(function (el) { 39 | return el.model === story; 40 | }); 41 | if (i === -1) { return }; 42 | 43 | subviews[i].remove(); 44 | subviews.splice(i, 1); 45 | }, 46 | 47 | render: function () { 48 | $('.navbar-nav').find('.new-story-header').remove(); 49 | $('.navbar-nav').find('.about-link').remove(); 50 | var topStories = this.stories.first(5); 51 | authors = []; 52 | Large.Collections.users.fetch(); 53 | topStories.forEach(function (story) { 54 | author = Large.Collections.users.get(story.get('author_id')) 55 | if (author !== undefined) { 56 | authors.push(author.get('email')); 57 | } 58 | }) 59 | var content = this.template({ 60 | tags: this.ttags, 61 | topStories: this.stories.first(5), 62 | authors: authors 63 | }) 64 | this.$el.html(content); 65 | this.attachSubviews(); 66 | 67 | var currentUser = Large.Collections.users.get(1) 68 | if (currentUser !== undefined) { 69 | $('.feed-username').append(this.currentUsername({ currentUser: currentUser })); 70 | } 71 | 72 | var newStory = new Large.Models.Story(); 73 | Large.Collections.publications.fetch(); 74 | var newStoryView = new Large.Views.NewStoryPreview({ 75 | parent: this, 76 | collection: this.stories, 77 | model: newStory, 78 | publications: Large.Collections.publications, 79 | ttags: this.ttags 80 | }); 81 | this.$('.post-click').append(newStoryView.render().$el); 82 | var editor = new MediumEditor('.editable', { 83 | placeholder: "", 84 | buttons: ['bold', 'italic', 'quote', 'anchor'] 85 | }); 86 | this.$("abbr.timeago").timeago(); 87 | return this; 88 | }, 89 | 90 | scrollSidebar: function (e) { 91 | var windowTop = $(window).scrollTop(); 92 | var sidebarTop = $('.sidebar').scrollTop(); 93 | 94 | if (!this.hovering) { 95 | $('.sidebar').css("padding-top", 100); 96 | $('.sidebar').prop("scrollTop", windowTop); 97 | } else if (windowTop > 71 && sidebarTop < 70) { 98 | $('.sidebar').css("padding-top", 32); 99 | } else { 100 | $('.sidebar').css("padding-top", 100); 101 | } 102 | }, 103 | 104 | handleEnter: function (e) { 105 | this.hovering = true; 106 | }, 107 | 108 | handleLeave: function (e) { 109 | this.hovering = false; 110 | }, 111 | 112 | showNewStory: function () { 113 | this.$('.post-click').css('display', 'block'); 114 | this.$('.pre-click').css('display', 'none'); 115 | $('.editable').focus(); 116 | }, 117 | 118 | hideNewStory: function () { 119 | this.$('.post-click').css('display', 'none'); 120 | this.$('.pre-click').css('display', 'block'); 121 | } 122 | }); 123 | -------------------------------------------------------------------------------- /app/assets/javascripts/views/pub_about.js: -------------------------------------------------------------------------------- 1 | Large.Views.PubAbout = Backbone.View.extend({ 2 | template: JST['publications/pub_about'], 3 | 4 | events: { 5 | "click .follow": "toggleFollow" 6 | }, 7 | 8 | initialize: function (options) { 9 | this.pub = options.pub; 10 | this.editors = this.pub.editors(); 11 | this.writers = this.pub.writers(); 12 | this.currentUserFollows = options.follows; 13 | this.listenTo(this.pub, 'sync', this.render); 14 | this.listenTo(this.currentUserFollows, 'sync', this.render); 15 | }, 16 | 17 | render: function () { 18 | $('.navbar-header').find('.about-link').remove(); 19 | $('.navbar-nav').find('.user-edit-toggle').remove(); 20 | var content = this.template({ 21 | pub: this.pub, 22 | writers: this.writers, 23 | editors: this.editors 24 | }); 25 | this.$el.html(content); 26 | 27 | $('.follow').each(function (i, obj) { 28 | var $id = parseInt($(obj).attr('id')); 29 | var $type = $(obj).val(); 30 | var follow = this.currentUserFollows.findWhere({ 31 | followable_id: $id, 32 | followable_type: $type }); 33 | if (!!follow) { 34 | $(obj).data('follow-state', 'followed'); 35 | } else { 36 | $(obj).data('follow-state', 'unfollowed'); 37 | } 38 | }.bind(this)); 39 | 40 | $('.follow').each(function (i, obj) { 41 | if ($(obj).data('follow-state') == "followed") { 42 | $(obj).html("Unfollow!"); 43 | } else { 44 | $(obj).html("Follow!"); 45 | } 46 | }); 47 | return this; 48 | }, 49 | 50 | toggleFollow: function (event) { 51 | var $id = parseInt($(event.currentTarget).attr('id')); 52 | var $type = $(event.currentTarget).val(); 53 | var follow = this.currentUserFollows.findWhere({ 54 | followable_id: $id, 55 | followable_type: $type }); 56 | 57 | if (follow === undefined) { 58 | follow = new Large.Models.Follow( { followable_id: $id, followable_type: $type }); 59 | follow.save(follow.attributes, { 60 | success: function () { 61 | $(event.currentTarget).data('follow-state', 'followed'); 62 | $(event.currentTarget).html("Unfollow!"); 63 | } 64 | }); 65 | } else { 66 | follow.destroy({ 67 | success: function (model, response) { 68 | $(event.currentTarget).data('follow-state', 'unfollowed'); 69 | $(event.currentTarget).html("Follow!"); 70 | } 71 | }); 72 | } 73 | } 74 | }) 75 | -------------------------------------------------------------------------------- /app/assets/javascripts/views/pub_edit.js: -------------------------------------------------------------------------------- 1 | Large.Views.PubEdit = Backbone.View.extend({ 2 | 3 | }); 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/views/pub_show.js: -------------------------------------------------------------------------------- 1 | Large.Views.PubShow = Backbone.View.extend({ 2 | template: JST['publications/pub_show'], 3 | 4 | about: JST['publications/pub_about_link'], 5 | 6 | events: { 7 | "click .follow": "toggleFollow" 8 | // "scroll": "blurImage" 9 | }, 10 | 11 | initialize: function (options) { 12 | this.pub = options.pub; 13 | this.stories = this.pub.stories(); 14 | this.publications = options.publications 15 | this.currentUserFollows = options.follows; 16 | 17 | this.numFollows = this.pub.followers(); 18 | this.listenTo(this.currentUserFollows, 'sync', this.render); 19 | this.listenTo(this.pub, 'sync', this.render); 20 | this.listenTo(this.stories, 'add', this.render); 21 | this.listenTo(this.publications, 'sync', this.render); 22 | }, 23 | 24 | render: function () { 25 | $('.navbar-header').find('.about-link').remove(); 26 | $('.navbar-nav').find('.user-edit-toggle').remove(); 27 | 28 | var headerContent = this.about({ 29 | pub: this.pub 30 | }); 31 | 32 | $('.navbar-header').append(headerContent); 33 | var content = this.template({ pub: this.pub, followers: this.numFollows }); 34 | this.$el.html(content); 35 | 36 | var follow = this.currentUserFollows.findWhere({ 37 | followable_id: this.pub.id, 38 | followable_type: "Publication" }); 39 | if (!!follow) { 40 | $('.follow').data('follow-state', 'followed'); 41 | } else { 42 | $('.follow').data('follow-state', 'unfollowed'); 43 | } 44 | 45 | if ($('.follow').data('follow-state') == "followed") { 46 | $('.follow').html("Unfollow!"); 47 | } else { 48 | $('.follow').html("Follow!"); 49 | } 50 | 51 | this.stories.models.forEach( function(story) { 52 | var storyPreview = new Large.Views.StoryPreview({ 53 | model: story, 54 | publications: this.publications, 55 | stories: this.stories }); 56 | this.$('ul.pub-stories').prepend(storyPreview.render().$el); 57 | }.bind(this)); 58 | this.$("abbr.timeago").timeago(); 59 | 60 | return this; 61 | }, 62 | 63 | toggleFollow: function (event) { 64 | var follow = this.currentUserFollows.findWhere({ 65 | followable_id: this.pub.id, 66 | followable_type: "Publication" }); 67 | 68 | if (follow === undefined) { 69 | follow = new Large.Models.Follow( { followable_id: this.pub.id, followable_type: "Publication" }); 70 | follow.save(follow.attributes, { 71 | success: function () { 72 | $(event.currentTarget).data('follow-state', 'followed'); 73 | $(event.currentTarget).html("Unfollow!"); 74 | } 75 | }); 76 | } else { 77 | follow.destroy({ 78 | success: function (model, response) { 79 | $(event.currentTarget).data('follow-state', 'unfollowed'); 80 | $(event.currentTarget).html("Follow!"); 81 | } 82 | }); 83 | } 84 | } 85 | }); 86 | -------------------------------------------------------------------------------- /app/assets/javascripts/views/story_edit.js: -------------------------------------------------------------------------------- 1 | Large.Views.StoryEdit = Backbone.View.extend({ 2 | 3 | }); 4 | -------------------------------------------------------------------------------- /app/assets/javascripts/views/story_preview.js: -------------------------------------------------------------------------------- 1 | Large.Views.StoryPreview = Backbone.View.extend({ 2 | template: JST['stories/story_preview'], 3 | inResponse: JST['stories/_in_response_link'], 4 | 5 | initialize: function (options) { 6 | this.publications = options.publications; 7 | this.stories = options.stories; 8 | this.allUsers = options.allUsers; 9 | 10 | this.listenTo(this.model, 'sync', this.render); 11 | this.listenTo(this.stories, 'sync', this.render); 12 | this.listenTo(Large.Collections.users, 'sync', this.render); 13 | this.listenTo(this.publications, 'sync', this.render); 14 | }, 15 | 16 | render: function () { 17 | var authorId = this.model.get('author_id'); 18 | var author = this.allUsers ? this.allUsers.get(authorId) || Large.Collections.users.get(authorId) : Large.Collections.users.get(authorId); 19 | // if (!author) { 20 | // return this; 21 | // } 22 | var pubId = this.model.get('pub_id'); 23 | var pub = this.publications.get(pubId); 24 | 25 | if ((this.model.get('body') === null) || (this.model.get("body").split('

').length < 3)) { 26 | var firstSentence = ""; 27 | var readingTime = "Less than a"; 28 | } else if (this.model.get('story_id') !== null) { 29 | var b = this.model.get('body'); 30 | var firstSentence = b.split('

')[0].split(">")[b.split('

')[0].split(">").length - 1] 31 | readingTime = Math.floor(this.model.get('body').length / 2800); 32 | if (readingTime === 0) { 33 | readingTime = "Less than a"; 34 | } 35 | } else { 36 | var b = this.model.get('body'); 37 | var firstSentence = b.split('

')[2].split(">")[b.split('

')[2].split(">").length - 1] 38 | readingTime = Math.floor(this.model.get('body').length / 2800); 39 | if (readingTime === 0) { 40 | readingTime = "Less than a"; 41 | } 42 | } 43 | 44 | var content = this.template({ 45 | story: this.model, 46 | author: author, 47 | authorId: authorId, 48 | pub: pub, 49 | sentence: firstSentence.slice(0, 250), 50 | readingTime: readingTime 51 | }); 52 | 53 | this.$el.html(content); 54 | this.$("abbr.timeago").timeago(); 55 | 56 | var responseId = this.model.get('story_id') 57 | var response = this.stories.get(responseId); 58 | 59 | if (response !== undefined) { 60 | this.$('.in-response').html(this.inResponse({response: response})); 61 | } 62 | 63 | return this; 64 | } 65 | }); 66 | -------------------------------------------------------------------------------- /app/assets/javascripts/views/story_preview_search.js: -------------------------------------------------------------------------------- 1 | Large.Views.StoryPreviewSearch = Backbone.View.extend({ 2 | template: JST['stories/story_preview_search'], 3 | 4 | initialize: function (options) { 5 | this.publications = options.publications; 6 | this.users = options.allUsers; 7 | 8 | // this.listenTo(Large.Collections.users, 'sync', this.render); 9 | this.listenTo(this.model, 'sync', this.render); 10 | this.listenTo(this.publications, 'sync', this.render); 11 | }, 12 | 13 | render: function () { 14 | // debugger 15 | var pubId = this.model.get('pub_id'); 16 | var pub = this.publications.get(pubId); 17 | 18 | var authorId = this.model.get('author_id'); 19 | var author = this.users.get(authorId); 20 | // if (!author) { 21 | // return this; 22 | // } 23 | var content = this.template({ story: this.model, author: author, pub: pub, authorId: authorId }); 24 | this.$el.html(content); 25 | this.$("abbr.timeago").timeago(); 26 | 27 | return this; 28 | } 29 | }); 30 | -------------------------------------------------------------------------------- /app/assets/javascripts/views/tag_show.js: -------------------------------------------------------------------------------- 1 | Large.Views.TagShow = Backbone.CompositeView.extend({ 2 | template: JST['tags/tag_show'], 3 | 4 | initialize: function (options) { 5 | this.ttag = options.ttag; 6 | this.ttags = options.ttags; 7 | this.taggedStories = options.ttag.taggedStories(); 8 | this.publications = options.pubs; 9 | this.allUsers = options.users; 10 | 11 | this.listenTo(this.publications, 'sync', this.render); 12 | this.listenTo(this.taggedStories, 'sync', this.render); 13 | this.listenTo(this.ttags, 'sync', this.render); 14 | 15 | this.taggedStories.each(this.addStoryView.bind(this)); 16 | this.listenTo(this.taggedStories, 'add', this.addStoryView); 17 | this.listenTo(this.taggedStories, 'remove', this.removeStoryView); 18 | }, 19 | 20 | render: function () { 21 | var content = this.template({ 22 | tag: this.ttag, 23 | tags: this.ttags 24 | }); 25 | 26 | this.$el.html(content); 27 | 28 | this.attachSubviews(); 29 | return this; 30 | }, 31 | 32 | addStoryView: function (story) { 33 | var storyPreview = new Large.Views.StoryPreview({ 34 | model: story, 35 | publications: this.publications, 36 | stories: this.taggedStories, 37 | allUsers: this.allUsers 38 | }); 39 | this.addSubview('ul', storyPreview); 40 | }, 41 | 42 | removeStoryView: function (story) { 43 | var subviews = this.subviews('ul'); 44 | var i = _(subviews).findIndex(function (el) { 45 | return el.model === story; 46 | }); 47 | if (i === -1) { return }; 48 | 49 | subviews[i].remove(); 50 | subviews.splice(i, 1); 51 | } 52 | }) 53 | -------------------------------------------------------------------------------- /app/assets/javascripts/views/user_edit.js: -------------------------------------------------------------------------------- 1 | Large.Views.UserEdit = Backbone.View.extend({ 2 | template: JST['users/user_edit'], 3 | 4 | events: { 5 | "click .follow": "toggleFollow", 6 | "click .user-header-image": "addHeaderImage", 7 | "click .save-edits": "saveEdits" 8 | }, 9 | 10 | initialize: function (options) { 11 | this.user = options.user; 12 | this.publications = options.publications; 13 | this.currentUserFollows = options.follows; 14 | 15 | this.follows = this.user.followers(); 16 | this.followings = this.user.followedUsers(); 17 | 18 | this.listenTo(this.user, 'sync', this.render); 19 | this.listenTo(this.publications, 'sync', this.render); 20 | }, 21 | 22 | render: function () { 23 | $('.navbar-nav').find('.user-edit-toggle').remove(); 24 | var content = this.template({ user: this.user, followers: this.follows, followings: this.followings }); 25 | this.$el.html(content); 26 | $('.edit-email').focus(); 27 | return this; 28 | }, 29 | 30 | addHeaderImage: function (event) { 31 | event.preventDefault(); 32 | 33 | filepicker.setKey("AFA8IlPkxSNC1BPrgoHtsz"); 34 | filepicker.pick( 35 | { 36 | mimetypes:'image/*', 37 | services:'COMPUTER' 38 | }, 39 | function (Blob) { 40 | var image = Blob.url; 41 | this.user.set("header_image", image); 42 | this.$('.user-header-image').css('background-image', "url('" + image + "')"); 43 | }.bind(this) 44 | ) 45 | }, 46 | 47 | saveEdits: function (event) { 48 | event.preventDefault(); 49 | if ($('.edit-email').val() === "") { 50 | $('#blankStoryError').modal('show'); 51 | setTimeout( function () { 52 | $('#blankStoryError').modal('hide'); 53 | }, 2500) 54 | } else { 55 | var formData = this.$('form').serializeJSON(); 56 | 57 | this.user.save(formData.user, { 58 | success: function () { 59 | Backbone.history.navigate("users/" + this.user.id, { trigger: true }); 60 | }.bind(this) 61 | }); 62 | } 63 | } 64 | 65 | }); 66 | -------------------------------------------------------------------------------- /app/assets/javascripts/views/user_show.js: -------------------------------------------------------------------------------- 1 | Large.Views.UserShow = Backbone.View.extend({ 2 | template: JST['users/user_show'], 3 | editToggle: JST['users/user_edit_toggle'], 4 | 5 | events: { 6 | "click .follow": "toggleFollow", 7 | "click .preview": "setTransitionState" 8 | }, 9 | 10 | initialize: function (options) { 11 | this.user = options.user; 12 | this.currentUser = options.currentUser; 13 | this.stories = this.user.stories(); 14 | this.publications = options.publications; 15 | this.currentUserFollows = options.follows; 16 | this.allStories = options.allStories; 17 | 18 | this.follows = this.user.followers(); 19 | this.followings = this.user.followedUsers(); 20 | this.transitioning = false; 21 | 22 | this.listenTo(this.currentUserFollows, 'sync add remove', this.render); 23 | this.listenTo(this.user, 'sync', this.render); 24 | this.listenTo(this.stories, 'sync', this.render); 25 | this.listenTo(this.publications, 'sync', this.render); 26 | this.listenTo(this.allStories, 'sync', this.render); 27 | }, 28 | 29 | render: function () { 30 | if (!this.transitioning) { 31 | $('.navbar-nav').find('.user-edit-toggle').remove(); 32 | 33 | var content = this.template({ user: this.user, followers: this.follows, followings: this.followings, headerImg: this.user.get('header_image') }); 34 | this.$el.html(content); 35 | 36 | var currentUser = this.currentUser.last(); 37 | if ((currentUser !== undefined) && (currentUser.id === this.user.id)) { 38 | $('.navbar-nav').prepend(this.editToggle({ currentUser: currentUser })); 39 | } 40 | 41 | var follow = this.currentUserFollows.findWhere({ 42 | followable_id: this.user.id, 43 | followable_type: "User" }); 44 | if (!!follow) { 45 | $('.follow').data('follow-state', 'followed'); 46 | } else { 47 | $('.follow').data('follow-state', 'unfollowed'); 48 | } 49 | 50 | if ($('.follow').data('follow-state') == "followed") { 51 | $('.follow').html("Unfollow!"); 52 | } else { 53 | $('.follow').html("Follow!"); 54 | } 55 | 56 | this.stories.models.forEach( function(story) { 57 | var storyPreview = new Large.Views.StoryPreview({ 58 | model: story, 59 | stories: this.allStories, 60 | publications: this.publications 61 | }); 62 | this.$('ul.user-stories').prepend(storyPreview.render().$el); 63 | this.$("abbr.timeago").timeago(); 64 | }.bind(this)); 65 | this.$("abbr.timeago").timeago(); 66 | 67 | return this; 68 | } 69 | }, 70 | 71 | setTransitionState: function (event) { 72 | this.transitioning = true; 73 | }, 74 | 75 | toggleFollow: function () { 76 | var follow = this.currentUserFollows.findWhere({ 77 | followable_id: this.user.id, 78 | followable_type: "User" }); 79 | 80 | if (follow === undefined) { 81 | follow = new Large.Models.Follow({ followable_id: this.user.id, followable_type: "User" }); 82 | follow.save(follow.attributes, { 83 | success: function () { 84 | $(event.currentTarget).data('follow-state', 'followed'); 85 | $(event.currentTarget).html("Unfollow!"); 86 | } 87 | }); 88 | } else { 89 | follow.destroy({ 90 | success: function (model, response) { 91 | $(event.currentTarget).data('follow-state', 'unfollowed'); 92 | $(event.currentTarget).html("Follow!"); 93 | } 94 | }); 95 | } 96 | } 97 | }); 98 | -------------------------------------------------------------------------------- /app/assets/javascripts/views/your_stories.js: -------------------------------------------------------------------------------- 1 | Large.Views.YourStories = Backbone.View.extend({ 2 | template: JST['stories/your_stories'], 3 | 4 | initialize: function (options) { 5 | this.user = options.user; 6 | this.publications = options.publications; 7 | 8 | this.listenTo(this.user, 'sync', this.render); 9 | this.listenTo(this.publications, 'sync', this.render); 10 | }, 11 | 12 | render: function () { 13 | var user = this.user.first(); 14 | if (user !== undefined) { 15 | var stories = user.stories(); 16 | } 17 | var content = this.template({ 18 | stories: stories, 19 | pubs: this.publications 20 | }); 21 | this.$el.html(content); 22 | return this; 23 | } 24 | }); 25 | -------------------------------------------------------------------------------- /app/assets/stylesheets/follows.css.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the follows controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/publication_edits.css.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the publication_edits controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/publication_writes.css.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the publication_writes controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/publications.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the publications controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/sessions.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the sessions controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/stories.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the stories controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/assets/stylesheets/users.scss: -------------------------------------------------------------------------------- 1 | // Place all the styles related to the users controller here. 2 | // They will automatically be included in application.css. 3 | // You can use Sass (SCSS) here: http://sass-lang.com/ 4 | -------------------------------------------------------------------------------- /app/assets/templates/feeds/_current_username.jst.ejs: -------------------------------------------------------------------------------- 1 | <%= currentUser.escape('email') %> 2 | -------------------------------------------------------------------------------- /app/assets/templates/feeds/feed_show.jst.ejs: -------------------------------------------------------------------------------- 1 |
2 | 3 |
4 |
5 |
6 | 7 |   Write Here... 8 | 9 |
10 |
11 | 12 |     13 | 14 |
15 |
16 | 18 |
19 | 20 |
21 | 22 |
23 |
24 | 25 | 66 | 67 |
68 |
69 | -------------------------------------------------------------------------------- /app/assets/templates/publications/new_pub.jst.ejs: -------------------------------------------------------------------------------- 1 |
2 | 3 | 4 | 5 |
6 |
7 |
8 | 9 |

10 |

11 |
12 |
13 |
14 |
15 |
16 |
17 | 19 | 21 |
22 |
23 | 24 |
25 |
26 | 27 | 36 | 37 | 40 | -------------------------------------------------------------------------------- /app/assets/templates/publications/pub_about.jst.ejs: -------------------------------------------------------------------------------- 1 |
2 |
3 |

ABOUT

4 |
5 |

<%= pub.escape('title') %>

6 | 7 |
8 |
9 |
10 |
11 |

NOTE FROM THE EDITOR

12 |

<%= pub.escape('description') %>

13 |
14 |
15 |
16 |

EDITORS

17 | 24 |
25 |
26 |
27 |

WRITERS

28 | 39 |
40 |
41 | -------------------------------------------------------------------------------- /app/assets/templates/publications/pub_about_link.jst.ejs: -------------------------------------------------------------------------------- 1 | About <%= pub.escape('title') %> 2 | -------------------------------------------------------------------------------- /app/assets/templates/publications/pub_index.jst.ejs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/app/assets/templates/publications/pub_index.jst.ejs -------------------------------------------------------------------------------- /app/assets/templates/publications/pub_show.jst.ejs: -------------------------------------------------------------------------------- 1 |
2 | <% if (pub.get('header_image') !== null) { %> 3 |
4 |
5 |
6 |
8 |

<%= pub.escape('title') %>

9 |

<%= pub.escape('description') %>

10 |
11 |
12 |
13 | <% } else { %> 14 |
15 |

<%= pub.escape('title') %>

16 |

<%= pub.escape('description') %>

17 |
18 | <% } %> 19 |
20 |
21 | 22 |
23 | 24 |
25 |
26 | 28 | 29 | 54 | 55 | -------------------------------------------------------------------------------- /app/assets/templates/stories/_author_username.jst.ejs: -------------------------------------------------------------------------------- 1 | <%= author.escape('email') %> 2 | on <%= date %> ‧ <%= readingTime %> min 3 | -------------------------------------------------------------------------------- /app/assets/templates/stories/_edit_and_delete_buttons.jst.ejs: -------------------------------------------------------------------------------- 1 |
  • 2 |
    3 | 8 | 16 |
    17 |
  • 18 | 19 | 31 | -------------------------------------------------------------------------------- /app/assets/templates/stories/_in_response_link.jst.ejs: -------------------------------------------------------------------------------- 1 | 3 | <%= response.escape('title') %> 4 | 5 | -------------------------------------------------------------------------------- /app/assets/templates/stories/_insert_toolbar.jst.ejs: -------------------------------------------------------------------------------- 1 |
    2 | 3 |
    4 | 7 | 8 |
    9 |
    10 | -------------------------------------------------------------------------------- /app/assets/templates/stories/_new_story_header.jst.ejs: -------------------------------------------------------------------------------- 1 |
    2 | 7 | 14 |
    15 | 23 | -------------------------------------------------------------------------------- /app/assets/templates/stories/new_story.jst.ejs: -------------------------------------------------------------------------------- 1 |
    2 | 6 |
    7 |
    8 | 9 |
    10 |
    11 | <% if (story.get('body') === undefined) {%> 12 |
    13 |


    14 |
    15 |
    16 |


    17 |
    18 |
    19 |


    20 |
    21 | <% } else { %> 22 |
    23 | <%= story.get('body') %> 24 |
    25 | <% } %> 26 |
    27 |
    28 | 29 | 60 | 61 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /app/assets/templates/stories/new_story_preview.jst.ejs: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |


    4 |


    5 |


    6 |
    7 |
    8 | 9 | 10 | 13 | 14 | 23 | -------------------------------------------------------------------------------- /app/assets/templates/stories/story_preview.jst.ejs: -------------------------------------------------------------------------------- 1 |
  • 2 | <% if (pub !== undefined) { %> 3 | <%= pub.escape('title') %>
    4 | 5 | <%= author? author.escape('email') : '' %> 6 | ‧ 7 | 8 | <%= story.get('created_at') %> 9 | 10 | <% } else { %> 11 | <%= author? author.escape('email') : '' %>
    12 | 13 | 14 | <%= story.get('created_at') %> 15 | 16 | 17 | <% } %> 18 | <% if (story.get('header_image') !== null) { %> 19 |
    20 |
    21 | 22 | 23 | 24 |
    25 | <% } %> 26 | 27 | <% if (story.get('story_id') === null) { %> 28 |

    <%= story.escape('title') %>

    29 |

    <%= story.escape('subtitle') %>

    30 | <% if (sentence !== "") { %> 31 |
    32 | <% if (sentence.length < 249) { %> 33 | <%= sentence %> 34 | <% } else { %> 35 | <%= sentence %>... 36 | <% } %> 37 |
    38 | <% } %> 39 |
    40 |
    Continue reading 41 | ‧ <%= readingTime %> min read 43 | <% } else { %> 44 |
    45 | 46 | in response to 47 |
    48 |
    49 |
    50 | <% if (sentence.length < 249) { %> 51 | <%= sentence %> 52 | <% } else { %> 53 | <%= sentence %>... 54 | <% } %> 55 |
    56 |
    57 | Continue reading 58 | ‧ <%= readingTime %> min read 60 | <% } %> 61 | 62 |
  • 63 | -------------------------------------------------------------------------------- /app/assets/templates/stories/story_preview_search.jst.ejs: -------------------------------------------------------------------------------- 1 |
  • 2 | <% if (story.get('header_image') !== null) { %> 3 |
    4 |
    5 | <% } %> 6 |
    7 | <% if (story.get('story_id') === null) { %> 8 | 9 |

    <%= story.escape('title') %>

    10 |

    <%= story.escape('subtitle') %>


    11 |
    12 | <% } else { %> 13 |
    14 | 15 | in response to 16 | 18 |

    <%= story.escape('title') %>

    19 |
    20 |
    21 | <% } %> 22 |
    23 | <% if (pub !== undefined) { %> 24 |

    In <%= pub.escape('title') %>, by 25 | <%= author ? author.escape('email') : '' %> 26 |
    27 | <%= story.get('created_at') %> 28 | <% } else { %> 29 | <%= author ? author.escape('email') : '' %>
    30 | 31 | <%= story.get('created_at') %> 32 | 33 | <% } %> 34 |

  • 35 | -------------------------------------------------------------------------------- /app/assets/templates/stories/story_show.jst.ejs: -------------------------------------------------------------------------------- 1 | <% if (response !== undefined) { %> 2 |
    3 | Written in reponse to: 4 |

    <%= response.escape('title') %>

    5 |
    6 | <% } %> 7 |
    8 | <% if (story.get('header_image') !== null) { %> 9 |
    10 |
    11 | 12 |
    13 | <% } %> 14 |
    15 | 16 |
    17 | <%= story.get('body') %> 18 |
    19 | <% if (tags.length > 0) { %> 20 |
    21 | TAGGED IN
    22 | <% tags.forEach( function (tag) { %> 23 | 24 | 27 | 28 | <% }) %> 29 | <% } %> 30 |
    31 |
    32 |
    33 |
    34 | 35 |   Write a response... 36 | 37 |
    38 |
    39 | 40 |   41 | 42 |
    43 |
    44 | 45 | 53 | -------------------------------------------------------------------------------- /app/assets/templates/stories/your_stories.jst.ejs: -------------------------------------------------------------------------------- 1 |

    Your Stories

    2 | 3 | 7 | 8 |
    9 | 10 |
    11 |
    12 | <% if (stories !== undefined) { %> 13 |
      14 | <% stories.forEach(function (story) { %> 15 |
    • <%= story.escape('title') %>
      <%= story.escape('subtitle') %>
    • 16 | <% }) %> 17 |
    18 | <% } else { %> 19 |
      20 |
    • Nothing to show.
    • 21 |
    22 | <% } %> 23 |
    24 |
    25 | 26 | 27 |
    28 |
    29 | <% if (pubs.length > 0) { %> 30 |
      31 | <% pubs.forEach( function (pub) { %> 32 |
    • <%= pub.escape('title') %>
    • 33 | <% }) %> 34 |
    35 | <% } else { %> 36 |
      37 |
    • Nothing to show.
    • 38 |
    39 | <% } %> 40 |
    41 |
    42 | 43 | 44 |
    45 | -------------------------------------------------------------------------------- /app/assets/templates/tags/tag_show.jst.ejs: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |

    TAGGED IN

    4 |

    <%= tag.escape('label') %>

    5 |
    6 | <% if (tags.length > 0) { %> 7 | 18 | <% } %> 19 | 21 |
    22 | -------------------------------------------------------------------------------- /app/assets/templates/users/user_edit_toggle.jst.ejs: -------------------------------------------------------------------------------- 1 |
  • 2 | 3 |
  • 4 | -------------------------------------------------------------------------------- /app/assets/templates/users/user_index.jst.ejs: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/app/assets/templates/users/user_index.jst.ejs -------------------------------------------------------------------------------- /app/assets/templates/users/user_show.jst.ejs: -------------------------------------------------------------------------------- 1 |
    2 | <% if (headerImg) { %> 3 |
    4 |
    5 | 6 | <% } else { %> 7 | 8 | <% } %> 9 |

    <%= user.escape('email') %>

    10 |

    <%= user.escape('description') %>

    11 | 12 | 13 |
    14 | 15 |
    16 |
    17 | 19 | 20 | 47 | 48 | 73 | -------------------------------------------------------------------------------- /app/controllers/api/api_controller.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | class ApiController < ApplicationController 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /app/controllers/api/follows_controller.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | 3 | class FollowsController < ApplicationController 4 | def create 5 | @follow = current_user.followings.new(follow_params) 6 | if @follow.save 7 | render json: @follow 8 | else 9 | render json: @follow.errors.full_messages, status: :unprocessable_entity 10 | end 11 | end 12 | 13 | def index 14 | if params[:current_user] 15 | @follows = current_user.followings 16 | else 17 | @follows = Follow.all 18 | end 19 | render json: @follows 20 | end 21 | 22 | def destroy 23 | @follow = Follow.find(params[:id]) 24 | @follow.destroy 25 | render json: {} 26 | end 27 | 28 | def follow_params 29 | params.require(:follow).permit(:follower_id, :followable_type, :followable_id) 30 | end 31 | end 32 | 33 | end 34 | -------------------------------------------------------------------------------- /app/controllers/api/publication_edits_controller.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | class PublicationEditsController < ApplicationController 3 | def create 4 | @pub_edit = PublicationEdit.new(pub_edit_params) 5 | if @pub_edit.save 6 | render json: @pub_edit 7 | else 8 | render json: @pub_edit.errors.full_messages, status: :unprocessable_entity 9 | end 10 | end 11 | 12 | def destroy 13 | @pub_edit = PublicationEdit.find(params[:id]) 14 | @pub_edit.destroy 15 | render json: {} 16 | end 17 | 18 | def index 19 | @pub_edits = PublicationEdit.all 20 | render json: @pub_edits 21 | end 22 | 23 | private 24 | def pub_edit_params 25 | params.require(:publication_edit).permit(:editor_id, :pub_id) 26 | end 27 | end 28 | 29 | end 30 | -------------------------------------------------------------------------------- /app/controllers/api/publication_writes_controller.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | class PublicationWritesController < ApplicationController 3 | def create 4 | @pub_write = PublicationWrite.new(pub_write_params) 5 | if @pub_write.save 6 | render json: @pub_write 7 | else 8 | render json: @pub_write.errors.full_messages, status: :unprocessable_entity 9 | end 10 | end 11 | 12 | def destroy 13 | @pub_write = PublicationWrite.find(params[:id]) 14 | @pub_write.destroy 15 | render json: {} 16 | end 17 | 18 | def index 19 | @pub_writes = PublicationWrite.all 20 | render json: @pub_writes 21 | end 22 | 23 | private 24 | def pub_write_params 25 | params.require(:publication_write).permit(:writer_id, :pub_id) 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /app/controllers/api/publications_controller.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | class PublicationsController < ApplicationController 3 | def create 4 | @pub = current_user.publications.new(pub_params) 5 | 6 | if @pub.save 7 | render json: @pub 8 | else 9 | render json: @pub.errors.full_messages, status: :unprocessable_entity 10 | end 11 | end 12 | 13 | def show 14 | @pub = Publication.includes(:stories, :followers, :tags, :taggings).find(params[:id]) 15 | render :show, include: :toggle_follow 16 | end 17 | 18 | def about 19 | @pub = Publication.includes(:pub_writes, :pub_edits, :editors, :writers).find(params[:id]) 20 | render :about 21 | end 22 | 23 | def index 24 | if params[:current_user] 25 | @pubs = current_user.publications 26 | elsif params[:query] 27 | search_params = "%#{params[:query]}%" 28 | @pubs = Publication.all.where("title ILIKE :search OR description ILIKE :search", search: search_params) 29 | else 30 | @pubs = Publication.all 31 | end 32 | render json: @pubs 33 | end 34 | 35 | def destroy 36 | @pub = current_user.publications.find(params[:id]) 37 | @pub.try(:destroy) 38 | render json: {} 39 | end 40 | 41 | def update 42 | @pub = current_user.publications.find(params[:id]) 43 | 44 | if @pub.update_attributes(pub_params) 45 | render json: @pub 46 | else 47 | render json: @pub.errors.full_messages, status: :unprocessable_entity 48 | end 49 | end 50 | 51 | def toggle_follow 52 | @pub = Publication.find(params[:id]) 53 | @follow = Follow.find_by( 54 | followable_id: @pub.id, followable_type: "Publication", follower_id: current_user.id 55 | ) 56 | 57 | if !!@follow 58 | @follow.destroy 59 | else 60 | @follow = Follow.create!( 61 | followable_id: @pub.id, followable_type: "Publication", follower_id: current_user.id 62 | ) 63 | end 64 | end 65 | 66 | private 67 | def pub_params 68 | params.require(:publication).permit(:title, :owner_id, :description, :header_image, :icon_image, :header_align) 69 | end 70 | end 71 | 72 | end 73 | -------------------------------------------------------------------------------- /app/controllers/api/search_controller.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | class SearchController < ApplicationController 3 | def show 4 | end 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /app/controllers/api/stories_controller.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | class StoriesController < ApplicationController 3 | def create 4 | @story = current_user.stories.new(story_params) 5 | 6 | if @story.save 7 | render json: @story 8 | else 9 | render json: @story.errors.full_messages, status: :unprocessable_entity 10 | end 11 | end 12 | 13 | def show 14 | @story = Story.includes(:tags, :taggings).find(params[:id]) 15 | render :show 16 | end 17 | 18 | def index 19 | #refactor this into the user model 20 | if params[:current_user] 21 | objects = [] 22 | current_user.followings.each do |following| 23 | if following.followable_type == "User" 24 | objects << User.find(following.followable_id) 25 | else 26 | objects << Publication.find(following.followable_id) 27 | end 28 | end 29 | @stories = [] 30 | objects.each do |object| 31 | object.stories.each do |story| 32 | @stories << story unless @stories.include?(story) 33 | end 34 | end 35 | elsif params[:query] 36 | search_params = "%#{params[:query]}%" 37 | @stories = Story.where("title ILIKE :search OR subtitle ILIKE :search OR body ILIKE :search", search: search_params).includes(:tags, :taggings) 38 | elsif params[:top_stories] 39 | @stories = Story.all[0..4] 40 | else 41 | @stories = Story.all 42 | end 43 | # fail 44 | render :index 45 | end 46 | 47 | def destroy 48 | @story = current_user.stories.find(params[:id]) 49 | @story.try(:destroy) 50 | render json: {} 51 | end 52 | 53 | def update 54 | @story = current_user.stories.find(params[:id]) 55 | 56 | if @story.update_attributes(story_params) 57 | render json: @story 58 | else 59 | render json: @story.errors.full_messages, status: :unprocessable_entity 60 | end 61 | end 62 | 63 | private 64 | def story_params 65 | params.require(:story).permit(:title, :author_id, :pub_id, :story_id, :subtitle, :body, :header_image, :created_at) 66 | end 67 | end 68 | end 69 | -------------------------------------------------------------------------------- /app/controllers/api/taggings_controller.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | class TaggingsController < ApplicationController 3 | def create 4 | @tagging = Tagging.new(tagging_params) 5 | if @tagging.save 6 | render json: @tagging 7 | else 8 | render json: @tagging.errors.full_messages, status: :unprocessable_entity 9 | end 10 | end 11 | 12 | def destroy 13 | @tagging = Tagging.find(params[:id]) 14 | @tagging.destroy 15 | render json: {} 16 | end 17 | 18 | def index 19 | @taggings = Tagging.all 20 | render json: @taggings 21 | end 22 | 23 | private 24 | def tagging_params 25 | params.require(:tagging).permit(:tag_id, :taggable_id, :taggable_type) 26 | end 27 | end 28 | end 29 | -------------------------------------------------------------------------------- /app/controllers/api/tags_controller.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | class TagsController < ApplicationController 3 | def create 4 | @tag = Tag.new(tag_params) 5 | if @tag.save 6 | render json: @tag 7 | else 8 | render json: @tag.errors.full_messages, status: :unproccessable_entity 9 | end 10 | end 11 | 12 | def index 13 | # if params[:query] 14 | # search_params = "%#{params[:query]}%" 15 | # @tags = Tag.all.where("label ILIKE :search", search: search_params) 16 | if params[:tag_id] 17 | tag = Tag.find(params[:tag_id]) 18 | @tags = [] 19 | tag.tagged_pubs.each do |pub| 20 | pub.tags.each do |tag| 21 | @tags << tag unless @tags.include?(tag) 22 | end 23 | end 24 | tag.tagged_stories.each do |story| 25 | story.tags.each do |tag| 26 | @tags << tag unless @tags.include?(tag) 27 | end 28 | end 29 | else 30 | @tags = Tag.all 31 | end 32 | render json: @tags 33 | end 34 | 35 | def show 36 | @tag = Tag.includes(:taggings).find(params[:id]) 37 | render :show, include: [:tagged_pubs, :tagged_stories] 38 | end 39 | 40 | def destroy 41 | end 42 | 43 | private 44 | 45 | def tag_params 46 | params.require(:tag).permit(:label) 47 | end 48 | end 49 | end 50 | -------------------------------------------------------------------------------- /app/controllers/api/users_controller.rb: -------------------------------------------------------------------------------- 1 | module Api 2 | class UsersController < ApplicationController 3 | def show 4 | @user = User.includes(:stories, :publications, :followers).find(params[:id]) 5 | render :show, include: [:followed_users] 6 | end 7 | 8 | def index 9 | if params[:query] 10 | search_params = "%#{params[:query]}%" 11 | @users = User.all.where("email ILIKE :search OR description ILIKE :search", search: search_params) 12 | elsif params[:current_user] 13 | @users = current_user 14 | else 15 | @users = User.all 16 | end 17 | render json: @users 18 | end 19 | 20 | def update 21 | @user = User.find(params[:id]) 22 | 23 | if @user.update_attributes(user_params) 24 | render json: @user 25 | else 26 | render json: @user.errors.full_messages, status: :unprocessable_entity 27 | end 28 | end 29 | 30 | def your_stories 31 | @user = User.includes(:stories, :publications).find(current_user.id) 32 | render :your_stories 33 | end 34 | 35 | def toggle_follow 36 | @user = User.find(params[:id]) 37 | @follow = Follow.find_by( 38 | followable_id: @user.id, followable_type: "User", follower_id: current_user.id 39 | ) 40 | 41 | if !!@follow 42 | @follow.destroy 43 | else 44 | @follow = Follow.create!( 45 | followable_id: @user.id, followable_type: "User", follower_id: current_user.id 46 | ) 47 | end 48 | end 49 | 50 | private 51 | 52 | def user_params 53 | params.require(:user).permit(:email, :password, :header_image, :icon_image, :description) 54 | end 55 | end 56 | end 57 | -------------------------------------------------------------------------------- /app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | # Prevent CSRF attacks by raising an exception. 3 | # For APIs, you may want to use :null_session instead. 4 | protect_from_forgery with: :exception 5 | 6 | helper_method :current_user, :signed_in? 7 | 8 | private 9 | 10 | def current_user 11 | return nil unless session[:token] 12 | @current_user ||= User.find_by_session_token(session[:token]) 13 | end 14 | 15 | def signed_in? 16 | !!current_user 17 | end 18 | 19 | def sign_in!(user) 20 | @current_user = user 21 | session[:token] = user.reset_token! 22 | end 23 | 24 | def sign_out! 25 | current_user.try(:reset_token!) 26 | session[:token] = nil 27 | end 28 | 29 | def require_signed_in! 30 | redirect_to new_session_url unless signed_in? 31 | end 32 | end 33 | -------------------------------------------------------------------------------- /app/controllers/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/app/controllers/concerns/.keep -------------------------------------------------------------------------------- /app/controllers/sessions_controller.rb: -------------------------------------------------------------------------------- 1 | class SessionsController < ApplicationController 2 | def new; end 3 | 4 | def create 5 | @user = User.find_by_credentials(params[:user]) 6 | 7 | if @user 8 | sign_in!(@user) 9 | redirect_to root_url 10 | else 11 | flash.now[:errors] = ["Invalid email and/or password"] 12 | render :new 13 | end 14 | end 15 | 16 | def destroy 17 | sign_out! 18 | redirect_to new_session_url 19 | end 20 | end 21 | -------------------------------------------------------------------------------- /app/controllers/static_pages_controller.rb: -------------------------------------------------------------------------------- 1 | class StaticPagesController < ApplicationController 2 | before_action :require_signed_in! 3 | 4 | def root; end 5 | end 6 | -------------------------------------------------------------------------------- /app/controllers/users_controller.rb: -------------------------------------------------------------------------------- 1 | class UsersController < ApplicationController 2 | def new; end 3 | 4 | def create 5 | @user = User.new(user_params) 6 | 7 | if @user.save 8 | sign_in!(@user) 9 | redirect_to root_url 10 | else 11 | flash.now[:errors] = @user.errors.full_messages 12 | render :new 13 | end 14 | end 15 | 16 | private 17 | 18 | def user_params 19 | params.require(:user).permit(:email, :password, :header_image, :icon_image, :description) 20 | end 21 | end 22 | -------------------------------------------------------------------------------- /app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/follows_helper.rb: -------------------------------------------------------------------------------- 1 | module FollowsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/publication_edits_helper.rb: -------------------------------------------------------------------------------- 1 | module PublicationEditsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/publication_writes_helper.rb: -------------------------------------------------------------------------------- 1 | module PublicationWritesHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/publications_helper.rb: -------------------------------------------------------------------------------- 1 | module PublicationsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/sessions_helper.rb: -------------------------------------------------------------------------------- 1 | module SessionsHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/stories_helper.rb: -------------------------------------------------------------------------------- 1 | module StoriesHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/helpers/users_helper.rb: -------------------------------------------------------------------------------- 1 | module UsersHelper 2 | end 3 | -------------------------------------------------------------------------------- /app/mailers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/app/mailers/.keep -------------------------------------------------------------------------------- /app/models/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/app/models/.keep -------------------------------------------------------------------------------- /app/models/concerns/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/app/models/concerns/.keep -------------------------------------------------------------------------------- /app/models/concerns/followable.rb: -------------------------------------------------------------------------------- 1 | module Followable 2 | extend ActiveSupport::Concern 3 | 4 | included do 5 | has_many :follows, as: :followable, 6 | class_name: :Follow, 7 | dependent: :destroy 8 | 9 | has_many :followers, 10 | through: :follows, 11 | source: :follower 12 | end 13 | 14 | def num_followers 15 | self.follows.length 16 | end 17 | 18 | end 19 | -------------------------------------------------------------------------------- /app/models/concerns/taggable.rb: -------------------------------------------------------------------------------- 1 | module Taggable 2 | extend ActiveSupport::Concern 3 | 4 | included do 5 | has_many :taggings, 6 | as: :taggable, 7 | class_name: :Tagging, 8 | dependent: :destroy 9 | 10 | has_many :tags, 11 | through: :taggings, 12 | source: :tag 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /app/models/follow.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: follows 4 | # 5 | # id :integer not null, primary key 6 | # followable_id :integer 7 | # follower_id :integer 8 | # followable_type :string 9 | # created_at :datetime not null 10 | # updated_at :datetime not null 11 | # 12 | 13 | class Follow < ActiveRecord::Base 14 | validates :follower_id, presence: true 15 | 16 | validates :follower_id, uniqueness: { scope: [:followable_id, :followable_type] } 17 | 18 | belongs_to :followable, polymorphic: true 19 | belongs_to :follower, class_name: :User, inverse_of: :followings 20 | end 21 | -------------------------------------------------------------------------------- /app/models/publication.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: publications 4 | # 5 | # id :integer not null, primary key 6 | # owner_id :integer not null 7 | # title :string not null 8 | # description :string 9 | # created_at :datetime not null 10 | # updated_at :datetime not null 11 | # header_image :text 12 | # icon_image :text 13 | # header_align :string 14 | # 15 | 16 | class Publication < ActiveRecord::Base 17 | include Followable 18 | include Taggable 19 | 20 | validates :owner_id, :title, presence: true 21 | 22 | has_many( 23 | :stories, 24 | class_name: :Story, 25 | foreign_key: :pub_id, 26 | primary_key: :id 27 | ) 28 | 29 | belongs_to( 30 | :owner, 31 | class_name: :User, 32 | foreign_key: :owner_id, 33 | primary_key: :id 34 | ) 35 | 36 | has_many( 37 | :pub_edits, 38 | class_name: :PublicationEdit, 39 | foreign_key: :pub_id, 40 | primary_key: :id 41 | ) 42 | 43 | has_many( 44 | :pub_writes, 45 | class_name: :PublicationWrite, 46 | foreign_key: :pub_id, 47 | primary_key: :id 48 | ) 49 | 50 | has_many :writers, through: :pub_writes, source: :writer 51 | has_many :editors, through: :pub_edits, source: :editor 52 | end 53 | -------------------------------------------------------------------------------- /app/models/publication_edit.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: publication_edits 4 | # 5 | # id :integer not null, primary key 6 | # editor_id :integer not null 7 | # pub_id :integer not null 8 | # created_at :datetime not null 9 | # updated_at :datetime not null 10 | # 11 | 12 | class PublicationEdit < ActiveRecord::Base 13 | validates :editor_id, :pub_id, presence: true 14 | validates :editor_id, uniqueness: { scope: [:pub_id] } 15 | 16 | belongs_to( 17 | :editor, 18 | class_name: :User, 19 | foreign_key: :editor_id, 20 | primary_key: :id 21 | ) 22 | 23 | belongs_to( 24 | :publication, 25 | class_name: :Publication, 26 | foreign_key: :pub_id, 27 | primary_key: :id 28 | ) 29 | end 30 | -------------------------------------------------------------------------------- /app/models/publication_write.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: publication_writes 4 | # 5 | # id :integer not null, primary key 6 | # writer_id :integer not null 7 | # pub_id :integer not null 8 | # created_at :datetime not null 9 | # updated_at :datetime not null 10 | # 11 | 12 | class PublicationWrite < ActiveRecord::Base 13 | validates :writer_id, :pub_id, presence: true 14 | validates :writer_id, uniqueness: { scope: [:pub_id] } 15 | 16 | belongs_to( 17 | :writer, 18 | class_name: :User, 19 | foreign_key: :writer_id, 20 | primary_key: :id 21 | ) 22 | 23 | belongs_to( 24 | :publication, 25 | class_name: :Publication, 26 | foreign_key: :pub_id, 27 | primary_key: :id 28 | ) 29 | end 30 | -------------------------------------------------------------------------------- /app/models/story.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: stories 4 | # 5 | # id :integer not null, primary key 6 | # author_id :integer not null 7 | # pub_id :string 8 | # title :string 9 | # subtitle :string 10 | # body :text 11 | # story_id :integer 12 | # created_at :datetime not null 13 | # updated_at :datetime not null 14 | # header_image :text 15 | # 16 | 17 | class Story < ActiveRecord::Base 18 | include Taggable 19 | validates :author_id, presence: true 20 | 21 | belongs_to( 22 | :author, 23 | class_name: :User, 24 | foreign_key: :author_id, 25 | primary_key: :id 26 | ) 27 | 28 | belongs_to( 29 | :publication, 30 | class_name: :Publication, 31 | foreign_key: :pub_id, 32 | primary_key: :id 33 | ) 34 | 35 | has_many( 36 | :responses, 37 | class_name: :Story, 38 | foreign_key: :story_id, 39 | primary_key: :id 40 | ) 41 | 42 | belongs_to( 43 | :story, 44 | class_name: :Story, 45 | foreign_key: :story_id, 46 | primary_key: :id 47 | ) 48 | end 49 | -------------------------------------------------------------------------------- /app/models/tag.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: tags 4 | # 5 | # id :integer not null, primary key 6 | # label :string not null 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | 11 | class Tag < ActiveRecord::Base 12 | validates :label, presence: true 13 | validates :label, uniqueness: true 14 | 15 | has_many( 16 | :taggings, 17 | class_name: :Tagging, 18 | foreign_key: :tag_id 19 | ) 20 | 21 | def tagged_pubs 22 | pubs = [] 23 | self.taggings.each do |tagging| 24 | if tagging.taggable_type == "Publication" 25 | pubs << Publication.includes(:tags, :taggings).find(tagging.taggable_id) 26 | end 27 | end 28 | return pubs 29 | end 30 | 31 | def tagged_stories 32 | stories = [] 33 | self.taggings.each do |tagging| 34 | if tagging.taggable_type == "Story" 35 | stories << Story.includes(:tags, :taggings).find(tagging.taggable_id) 36 | end 37 | end 38 | return stories 39 | end 40 | 41 | end 42 | -------------------------------------------------------------------------------- /app/models/tagging.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: taggings 4 | # 5 | # id :integer not null, primary key 6 | # taggable_id :integer not null 7 | # tag_id :integer not null 8 | # taggable_type :string not null 9 | # created_at :datetime not null 10 | # updated_at :datetime not null 11 | # 12 | 13 | class Tagging < ActiveRecord::Base 14 | validates :taggable_id, :tag_id, :taggable_type, presence: true 15 | validates :tag_id, uniqueness: { scope: [:taggable_id, :taggable_type] } 16 | 17 | belongs_to :taggable, polymorphic: true 18 | belongs_to :tag, inverse_of: :taggings 19 | end 20 | -------------------------------------------------------------------------------- /app/models/user.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: users 4 | # 5 | # id :integer not null, primary key 6 | # email :string not null 7 | # password_digest :string not null 8 | # session_token :string not null 9 | # created_at :datetime not null 10 | # updated_at :datetime not null 11 | # description :string 12 | # header_image :text 13 | # icon_image :text 14 | # 15 | 16 | class User < ActiveRecord::Base 17 | include Followable 18 | 19 | validates :email, :session_token, presence: true 20 | validates :password, length: { minimum: 6, allow_nil: true } 21 | validates :email, uniqueness: true 22 | 23 | has_many( 24 | :publications, 25 | class_name: :Publication, 26 | foreign_key: :owner_id, 27 | primary_key: :id 28 | ) 29 | 30 | has_many( 31 | :stories, 32 | class_name: :Story, 33 | foreign_key: :author_id, 34 | primary_key: :id 35 | ) 36 | 37 | has_many( 38 | :followings, 39 | class_name: :Follow, 40 | foreign_key: :follower_id 41 | ) 42 | 43 | has_many( 44 | :pub_edits, 45 | class_name: :PublicationEdit, 46 | foreign_key: :editor_id, 47 | primary_key: :id 48 | ) 49 | 50 | has_many( 51 | :pub_writes, 52 | class_name: :PublicationWrite, 53 | foreign_key: :writer_id, 54 | primary_key: :id 55 | ) 56 | 57 | has_many :contributed_pubs, through: :pub_writes, source: :publication 58 | has_many :edited_pubs, through: :pub_edits, source: :publication 59 | 60 | attr_reader :password 61 | after_initialize :ensure_session_token 62 | 63 | def gravatar_url 64 | "http://www.gravatar.com/avatar/#{ Digest::MD5.hexdigest(email) }" 65 | end 66 | 67 | def self.find_by_credentials(user_params) 68 | user = User.find_by_email(user_params[:email]) 69 | user.try(:is_password?, user_params[:password]) ? user : nil 70 | end 71 | 72 | def password=(password) 73 | @password = password 74 | self.password_digest = BCrypt::Password.create(password) 75 | end 76 | 77 | def is_password?(password) 78 | BCrypt::Password.new(self.password_digest).is_password?(password) 79 | end 80 | 81 | def reset_token! 82 | self.session_token = SecureRandom.urlsafe_base64(16) 83 | self.save! 84 | self.session_token 85 | end 86 | 87 | def followed_users 88 | users = [] 89 | self.followings.each do |following| 90 | if following.followable_type == "User" 91 | users << User.find(following.followable_id) 92 | end 93 | end 94 | return users 95 | end 96 | 97 | protected 98 | 99 | def ensure_session_token 100 | self.session_token ||= SecureRandom.urlsafe_base64(16) 101 | end 102 | 103 | end 104 | -------------------------------------------------------------------------------- /app/views/api/follows/_follow.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract!(follow, :id, :follower_id, :followable_type, :followable_id) 2 | -------------------------------------------------------------------------------- /app/views/api/follows/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial!("follow", follow: @follow) 2 | -------------------------------------------------------------------------------- /app/views/api/pub_edits/_pubedit.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract!(pubedit, :id, :editor_id, :pub_id) 2 | -------------------------------------------------------------------------------- /app/views/api/pub_edits/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial!("pubedit", pubedit: @pubedit) 2 | -------------------------------------------------------------------------------- /app/views/api/pub_writes/_pubwrite.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract!(pubwrite, :id, :writer_id, :pub_id) 2 | -------------------------------------------------------------------------------- /app/views/api/pub_writes/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial!("pubwrite", pubwrite: @pubwrite) 2 | -------------------------------------------------------------------------------- /app/views/api/publications/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/app/views/api/publications/.keep -------------------------------------------------------------------------------- /app/views/api/publications/_pub.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract!(pub, :id, :title, :description, :owner_id, :header_image, :icon_image, :header_align) 2 | -------------------------------------------------------------------------------- /app/views/api/publications/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial!("pub", pub: @pub) 2 | 3 | json.stories do 4 | json.array!(@pub.stories) do |story| 5 | json.partial! 'api/stories/story', story: story 6 | end 7 | end 8 | 9 | json.follows do 10 | json.array!(@pub.follows) do |follow| 11 | json.partial! 'api/follows/follow', follow: follow 12 | end 13 | end 14 | 15 | json.editors do 16 | json.array!(@pub.editors) do |editor| 17 | json.partial! 'api/users/user', user: editor 18 | end 19 | end 20 | 21 | json.writers do 22 | json.array!(@pub.writers) do |writer| 23 | json.partial! 'api/users/user', user: writer 24 | end 25 | end 26 | 27 | json.pub_edits do 28 | json.array!(@pub.pub_edits) do |pub_edit| 29 | json.partial! 'api/pub_edits/pubedit', pubedit: pub_edit 30 | end 31 | end 32 | 33 | json.pub_writes do 34 | json.array!(@pub.pub_writes) do |pub_write| 35 | json.partial! 'api/pub_writes/pubwrite', pubwrite: pub_write 36 | end 37 | end 38 | 39 | json.followers do 40 | json.array!(@pub.followers) do |follower| 41 | json.partial! 'api/users/user', user: follower 42 | end 43 | end 44 | 45 | json.taggings do 46 | json.array!(@pub.taggings) do |tagging| 47 | json.partial! 'api/taggings/tagging', tagging: tagging 48 | end 49 | end 50 | 51 | json.tags do 52 | json.array!(@pub.tags) do |tag| 53 | json.partial! 'api/tags/tag', tag: tag 54 | end 55 | end 56 | -------------------------------------------------------------------------------- /app/views/api/stories/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/app/views/api/stories/.keep -------------------------------------------------------------------------------- /app/views/api/stories/_story.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract!(story, :id, :created_at, :title, :subtitle, :body, :pub_id, :author_id, :story_id, :header_image) 2 | -------------------------------------------------------------------------------- /app/views/api/stories/index.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.array!(@stories) do |story| 2 | json.partial! 'api/stories/story', story: story 3 | 4 | json.taggings do 5 | json.array!(story.taggings) do |tagging| 6 | json.partial! 'api/taggings/tagging', tagging: tagging 7 | end 8 | end 9 | 10 | json.tags do 11 | json.array!(story.tags) do |tag| 12 | json.partial! 'api/tags/tag', tag: tag 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /app/views/api/stories/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial!("story", story: @story) 2 | 3 | json.taggings do 4 | json.array!(@story.taggings) do |tagging| 5 | json.partial! 'api/taggings/tagging', tagging: tagging 6 | end 7 | end 8 | 9 | json.tags do 10 | json.array!(@story.tags) do |tag| 11 | json.partial! 'api/tags/tag', tag: tag 12 | end 13 | end 14 | -------------------------------------------------------------------------------- /app/views/api/taggings/_tagging.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract!(tagging, :id, :tag_id, :taggable_id, :taggable_type) 2 | -------------------------------------------------------------------------------- /app/views/api/taggings/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial!("tagging", tagging: @tagging) 2 | -------------------------------------------------------------------------------- /app/views/api/tags/_tag.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract!(tag, :id, :label) 2 | -------------------------------------------------------------------------------- /app/views/api/tags/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial!("tag", tag: @tag) 2 | 3 | json.taggings do 4 | json.array!(@tag.taggings) do |tagging| 5 | json.partial! 'api/taggings/tagging', tagging: tagging 6 | end 7 | end 8 | 9 | json.tagged_pubs do 10 | json.array!(@tag.tagged_pubs) do |pub| 11 | json.partial! 'api/publications/pub', pub: pub 12 | end 13 | end 14 | 15 | json.tagged_stories do 16 | json.array!(@tag.tagged_stories) do |story| 17 | json.partial! 'api/stories/story', story: story 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /app/views/api/users/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/app/views/api/users/.keep -------------------------------------------------------------------------------- /app/views/api/users/_user.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.extract!(user, :id, :email, :description, :header_image, :icon_image) 2 | -------------------------------------------------------------------------------- /app/views/api/users/show.json.jbuilder: -------------------------------------------------------------------------------- 1 | json.partial!("user", user: @user) 2 | 3 | json.stories do 4 | json.array!(@user.stories) do |story| 5 | json.partial! 'api/stories/story', story: story 6 | end 7 | end 8 | 9 | json.publications do 10 | json.array!(@user.publications) do |pub| 11 | json.partial! 'api/publications/pub', pub: pub 12 | end 13 | end 14 | 15 | json.followers do 16 | json.array!(@user.followers) do |follower| 17 | json.partial! 'api/users/user', user: follower 18 | end 19 | end 20 | 21 | json.followed_users do 22 | json.array!(@user.followed_users) do |user| 23 | json.partial! 'api/users/user', user: user 24 | end 25 | end 26 | 27 | # json.partial! 'api/users/user', user: current_user 28 | 29 | 30 | json.follows do 31 | json.array!(@user.follows) do |follow| 32 | json.partial! 'api/follows/follow', follow: follow 33 | end 34 | end 35 | 36 | json.followings do 37 | json.array!(@user.followings) do |following| 38 | json.partial! 'api/follows/follow', follow: following 39 | end 40 | end 41 | 42 | json.edited_pubs do 43 | json.array!(@user.edited_pubs) do |pub| 44 | json.partial! 'api/publications/pub', pub: pub 45 | end 46 | end 47 | 48 | json.contributed_pubs do 49 | json.array!(@user.contributed_pubs) do |pub| 50 | json.partial! 'api/publications/pub', pub: pub 51 | end 52 | end 53 | -------------------------------------------------------------------------------- /app/views/layouts/_header.html.erb: -------------------------------------------------------------------------------- 1 | 30 | 31 | <% if flash[:errors] %> 32 | 36 | <% end %> 37 | -------------------------------------------------------------------------------- /app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | Large 6 | <%= stylesheet_link_tag 'application', media: 'all' %> 7 | <%= javascript_include_tag 'application' %> 8 | <%= csrf_meta_tags %> 9 | 10 | 11 | 12 | 13 | 14 | <%= render partial: "layouts/header" %> 15 | <%= yield %> 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /app/views/sessions/new.html.erb: -------------------------------------------------------------------------------- 1 | 109 | 110 |
    111 |
    Curl up with a BIG idea
    112 |
    113 |
    114 | 115 | 118 | 119 | 123 |
    124 |
    125 | 129 |
    130 | 131 | 132 | 133 |
    134 | 135 | 136 |
    137 |
    138 | 139 | 148 | -------------------------------------------------------------------------------- /app/views/static_pages/root.html.erb: -------------------------------------------------------------------------------- 1 |
    2 |
    3 |
    4 |
    5 | 6 | 11 | -------------------------------------------------------------------------------- /app/views/users/new.html.erb: -------------------------------------------------------------------------------- 1 | 74 | 75 |
    76 |
    77 |

    Sign Up

    78 |
    79 | 80 | 83 | 84 | 88 |
    89 |
    90 | 94 |
    95 | 96 | 97 | 98 |
    99 |
    100 |
    101 | -------------------------------------------------------------------------------- /bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path("../spring", __FILE__) 4 | rescue LoadError 5 | end 6 | APP_PATH = File.expand_path('../../config/application', __FILE__) 7 | require_relative '../config/boot' 8 | require 'rails/commands' 9 | -------------------------------------------------------------------------------- /bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | begin 3 | load File.expand_path("../spring", __FILE__) 4 | rescue LoadError 5 | end 6 | require_relative '../config/boot' 7 | require 'rake' 8 | Rake.application.run 9 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'pathname' 3 | 4 | # path to your application root. 5 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) 6 | 7 | Dir.chdir APP_ROOT do 8 | # This script is a starting point to setup your application. 9 | # Add necessary setup steps to this file: 10 | 11 | puts "== Installing dependencies ==" 12 | system "gem install bundler --conservative" 13 | system "bundle check || bundle install" 14 | 15 | # puts "\n== Copying sample files ==" 16 | # unless File.exist?("config/database.yml") 17 | # system "cp config/database.yml.sample config/database.yml" 18 | # end 19 | 20 | puts "\n== Preparing database ==" 21 | system "bin/rake db:setup" 22 | 23 | puts "\n== Removing old logs and tempfiles ==" 24 | system "rm -f log/*" 25 | system "rm -rf tmp/cache" 26 | 27 | puts "\n== Restarting application server ==" 28 | system "touch tmp/restart.txt" 29 | end 30 | -------------------------------------------------------------------------------- /bin/spring: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | # This file loads spring without using Bundler, in order to be fast. 4 | # It gets overwritten when you run the `spring binstub` command. 5 | 6 | unless defined?(Spring) 7 | require "rubygems" 8 | require "bundler" 9 | 10 | if match = Bundler.default_lockfile.read.match(/^GEM$.*?^ (?: )*spring \((.*?)\)$.*?^$/m) 11 | Gem.paths = { "GEM_PATH" => [Bundler.bundle_path.to_s, *Gem.path].uniq.join(Gem.path_separator) } 12 | gem "spring", match[1] 13 | require "spring/binstub" 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Rails.application 5 | -------------------------------------------------------------------------------- /config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | require 'rails/all' 4 | 5 | # Require the gems listed in Gemfile, including any gems 6 | # you've limited to :test, :development, or :production. 7 | Bundler.require(*Rails.groups) 8 | 9 | module Large 10 | class Application < Rails::Application 11 | # Settings in config/environments/* take precedence over those specified here. 12 | # Application configuration should go into files in config/initializers 13 | # -- all .rb files in that directory are automatically loaded. 14 | 15 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 16 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 17 | # config.time_zone = 'Central Time (US & Canada)' 18 | 19 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 20 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 21 | # config.i18n.default_locale = :de 22 | 23 | # Do not swallow errors in after_commit/after_rollback callbacks. 24 | # config.active_record.raise_in_transactional_callbacks = true 25 | end 26 | end 27 | -------------------------------------------------------------------------------- /config/boot.rb: -------------------------------------------------------------------------------- 1 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 2 | 3 | require 'bundler/setup' # Set up gems listed in the Gemfile. 4 | -------------------------------------------------------------------------------- /config/database.yml: -------------------------------------------------------------------------------- 1 | # PostgreSQL. Versions 8.2 and up are supported. 2 | # 3 | # Install the pg driver: 4 | # gem install pg 5 | # On OS X with Homebrew: 6 | # gem install pg -- --with-pg-config=/usr/local/bin/pg_config 7 | # On OS X with MacPorts: 8 | # gem install pg -- --with-pg-config=/opt/local/lib/postgresql84/bin/pg_config 9 | # On Windows: 10 | # gem install pg 11 | # Choose the win32 build. 12 | # Install PostgreSQL and put its /bin directory on your path. 13 | # 14 | # Configure Using Gemfile 15 | # gem 'pg' 16 | # 17 | default: &default 18 | adapter: postgresql 19 | encoding: unicode 20 | # For details on connection pooling, see rails configuration guide 21 | # http://guides.rubyonrails.org/configuring.html#database-pooling 22 | pool: 5 23 | 24 | development: 25 | <<: *default 26 | database: Large_development 27 | 28 | # The specified database role being used to connect to postgres. 29 | # To create additional roles in postgres see `$ createuser --help`. 30 | # When left blank, postgres will use the default role. This is 31 | # the same name as the operating system user that initialized the database. 32 | #username: Large 33 | 34 | # The password associated with the postgres role (username). 35 | #password: 36 | 37 | # Connect on a TCP socket. Omitted by default since the client uses a 38 | # domain socket that doesn't need configuration. Windows does not have 39 | # domain sockets, so uncomment these lines. 40 | #host: localhost 41 | 42 | # The TCP port the server listens on. Defaults to 5432. 43 | # If your server runs on a different port number, change accordingly. 44 | #port: 5432 45 | 46 | # Schema search path. The server defaults to $user,public 47 | #schema_search_path: myapp,sharedapp,public 48 | 49 | # Minimum log levels, in increasing order: 50 | # debug5, debug4, debug3, debug2, debug1, 51 | # log, notice, warning, error, fatal, and panic 52 | # Defaults to warning. 53 | #min_messages: notice 54 | 55 | # Warning: The database defined as "test" will be erased and 56 | # re-generated from your development database when you run "rake". 57 | # Do not set this db to the same as development or production. 58 | test: 59 | <<: *default 60 | database: Large_test 61 | 62 | # As with config/secrets.yml, you never want to store sensitive information, 63 | # like your database password, in your source code. If your source code is 64 | # ever seen by anyone, they now have access to your database. 65 | # 66 | # Instead, provide the password as a unix environment variable when you boot 67 | # the app. Read http://guides.rubyonrails.org/configuring.html#configuring-a-database 68 | # for a full rundown on how to provide these environment variables in a 69 | # production deployment. 70 | # 71 | # On Heroku and other platform providers, you may have a full connection URL 72 | # available as an environment variable. For example: 73 | # 74 | # DATABASE_URL="postgres://myuser:mypass@localhost/somedatabase" 75 | # 76 | # You can use this database configuration with: 77 | # 78 | # production: 79 | # url: <%= ENV['DATABASE_URL'] %> 80 | # 81 | production: 82 | <<: *default 83 | database: Large_production 84 | username: Large 85 | password: <%= ENV['LARGE_DATABASE_PASSWORD'] %> 86 | -------------------------------------------------------------------------------- /config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Do not eager load code on boot. 10 | config.eager_load = false 11 | 12 | # Show full error reports and disable caching. 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send. 17 | config.action_mailer.raise_delivery_errors = false 18 | 19 | # Print deprecation notices to the Rails logger. 20 | config.active_support.deprecation = :log 21 | 22 | # Raise an error on page load if there are pending migrations. 23 | config.active_record.migration_error = :page_load 24 | 25 | # Debug mode disables concatenation and preprocessing of assets. 26 | # This option may cause significant delays in view rendering with a large 27 | # number of complex assets. 28 | config.assets.debug = true 29 | 30 | # Asset digests allow you to set far-future HTTP expiration dates on all assets, 31 | # yet still be able to expire them through the digest params. 32 | config.assets.digest = true 33 | 34 | # Adds additional error checking when serving assets at runtime. 35 | # Checks for improperly declared sprockets dependencies. 36 | # Raises helpful error messages. 37 | config.assets.raise_runtime_errors = true 38 | 39 | # Raises error for missing translations 40 | # config.action_view.raise_on_missing_translations = true 41 | end 42 | -------------------------------------------------------------------------------- /config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # Code is not reloaded between requests. 5 | config.cache_classes = true 6 | 7 | # Eager load code on boot. This eager loads most of Rails and 8 | # your application in memory, allowing both threaded web servers 9 | # and those relying on copy on write to perform better. 10 | # Rake tasks automatically ignore this option for performance. 11 | config.eager_load = true 12 | 13 | # Full error reports are disabled and caching is turned on. 14 | config.consider_all_requests_local = false 15 | config.action_controller.perform_caching = true 16 | 17 | # Enable Rack::Cache to put a simple HTTP cache in front of your application 18 | # Add `rack-cache` to your Gemfile before enabling this. 19 | # For large-scale production use, consider using a caching reverse proxy like 20 | # NGINX, varnish or squid. 21 | # config.action_dispatch.rack_cache = true 22 | 23 | # Disable serving static files from the `/public` folder by default since 24 | # Apache or NGINX already handles this. 25 | # config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present? 26 | config.serve_static_files = true 27 | 28 | # Compress JavaScripts and CSS. 29 | config.assets.js_compressor = Uglifier.new(harmony: true) 30 | # config.assets.css_compressor = :sass 31 | 32 | # Do not fallback to assets pipeline if a precompiled asset is missed. 33 | config.assets.compile = false 34 | 35 | # Asset digests allow you to set far-future HTTP expiration dates on all assets, 36 | # yet still be able to expire them through the digest params. 37 | config.assets.digest = true 38 | 39 | # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb 40 | 41 | # Specifies the header that your server uses for sending files. 42 | # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache 43 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX 44 | 45 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 46 | # config.force_ssl = true 47 | 48 | # Use the lowest log level to ensure availability of diagnostic information 49 | # when problems arise. 50 | config.log_level = :debug 51 | 52 | # Prepend all log lines with the following tags. 53 | # config.log_tags = [ :subdomain, :uuid ] 54 | 55 | # Use a different logger for distributed setups. 56 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) 57 | 58 | # Use a different cache store in production. 59 | # config.cache_store = :mem_cache_store 60 | 61 | # Enable serving of images, stylesheets, and JavaScripts from an asset server. 62 | # config.action_controller.asset_host = 'http://assets.example.com' 63 | 64 | # Ignore bad email addresses and do not raise email delivery errors. 65 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 66 | # config.action_mailer.raise_delivery_errors = false 67 | 68 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 69 | # the I18n.default_locale when a translation cannot be found). 70 | config.i18n.fallbacks = true 71 | 72 | # Send deprecation notices to registered listeners. 73 | config.active_support.deprecation = :notify 74 | 75 | # Use default logging formatter so that PID and timestamp are not suppressed. 76 | config.log_formatter = ::Logger::Formatter.new 77 | 78 | # Do not dump schema after migrations. 79 | config.active_record.dump_schema_after_migration = false 80 | end 81 | -------------------------------------------------------------------------------- /config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Do not eager load code on boot. This avoids loading your whole application 11 | # just for the purpose of running a single test. If you are using a tool that 12 | # preloads Rails for running tests, you may have to set it to true. 13 | config.eager_load = false 14 | 15 | # Configure static file server for tests with Cache-Control for performance. 16 | config.serve_static_files = true 17 | config.static_cache_control = 'public, max-age=3600' 18 | 19 | # Show full error reports and disable caching. 20 | config.consider_all_requests_local = true 21 | config.action_controller.perform_caching = false 22 | 23 | # Raise exceptions instead of rendering exception templates. 24 | config.action_dispatch.show_exceptions = false 25 | 26 | # Disable request forgery protection in test environment. 27 | config.action_controller.allow_forgery_protection = false 28 | 29 | # Tell Action Mailer not to deliver emails to the real world. 30 | # The :test delivery method accumulates sent emails in the 31 | # ActionMailer::Base.deliveries array. 32 | config.action_mailer.delivery_method = :test 33 | 34 | # Randomize the order test cases are executed. 35 | config.active_support.test_order = :random 36 | 37 | # Print deprecation notices to the stderr. 38 | config.active_support.deprecation = :stderr 39 | 40 | # Raises error for missing translations 41 | # config.action_view.raise_on_missing_translations = true 42 | end 43 | -------------------------------------------------------------------------------- /config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = '1.0' 5 | 6 | # Add additional assets to the asset load path 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | 9 | # Precompile additional assets. 10 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. 11 | # Rails.application.config.assets.precompile += %w( search.js ) 12 | -------------------------------------------------------------------------------- /config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.action_dispatch.cookies_serializer = :json 4 | -------------------------------------------------------------------------------- /config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'RESTful' 16 | # end 17 | -------------------------------------------------------------------------------- /config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.session_store :cookie_store, key: '_Large_session' 4 | -------------------------------------------------------------------------------- /config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] if respond_to?(:wrap_parameters) 9 | end 10 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /config/locales/en.yml: -------------------------------------------------------------------------------- 1 | # Files in the config/locales directory are used for internationalization 2 | # and are automatically loaded by Rails. If you want to use locales other 3 | # than English, add the necessary files in this directory. 4 | # 5 | # To use the locales, use `I18n.t`: 6 | # 7 | # I18n.t 'hello' 8 | # 9 | # In views, this is aliased to just `t`: 10 | # 11 | # <%= t('hello') %> 12 | # 13 | # To use a different locale, set it with `I18n.locale`: 14 | # 15 | # I18n.locale = :es 16 | # 17 | # This would use the information in config/locales/es.yml. 18 | # 19 | # To learn more, please read the Rails Internationalization guide 20 | # available at http://guides.rubyonrails.org/i18n.html. 21 | 22 | en: 23 | hello: "Hello world" 24 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | root to: "static_pages#root" 3 | 4 | resources :users, except: [:show, :index] 5 | resource :session, only: [:new, :create, :destroy] 6 | 7 | namespace :api, defaults: { format: :json } do 8 | resources :publications do 9 | member do 10 | get :about 11 | end 12 | end 13 | resource :search, only: [:show] 14 | resources :stories 15 | resources :users, except: [:destroy] 16 | # do 17 | # member do 18 | # get :your_stories 19 | # end 20 | # end 21 | resources :follows, only: [:create, :destroy, :index] 22 | resources :taggings 23 | resources :tags 24 | resources :publication_edits, only: [:create, :index, :destroy] 25 | resources :publication_writes, only: [:create, :index, :destroy] 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /config/secrets.yml: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rake secret` to generate a secure secret key. 9 | 10 | # Make sure the secrets in this file are kept private 11 | # if you're sharing your code publicly. 12 | 13 | development: 14 | secret_key_base: 7e518e264e365b78025bc988317cd177f78cb1e9c3bbaf268819b028b32d21329d67d1f383428416dc0b3f61cb177c7981397dcd8aacd21b4c42ac9a3bb73804 15 | 16 | test: 17 | secret_key_base: bbddaf0ccaba48fb545d79e613e8918f9edc365ab3a1bb117c4b44046e504496407afd9bf2f972b56277a71e649afe86e9c9fffda2ac1a1f293ff252621f71ad 18 | 19 | # Do not keep production secrets in the repository, 20 | # instead read values from the environment. 21 | production: 22 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> 23 | -------------------------------------------------------------------------------- /config/storage.yml: -------------------------------------------------------------------------------- 1 | test: 2 | service: Disk 3 | root: <%= Rails.root.join("tmp/storage") %> 4 | 5 | local: 6 | service: Disk 7 | root: <%= Rails.root.join("storage") %> 8 | 9 | # Use rails credentials:edit to set the AWS secrets (as aws:access_key_id|secret_access_key) 10 | # amazon: 11 | # service: S3 12 | # access_key_id: <%= Rails.application.credentials.dig(:aws, :access_key_id) %> 13 | # secret_access_key: <%= Rails.application.credentials.dig(:aws, :secret_access_key) %> 14 | # region: us-east-1 15 | # bucket: your_own_bucket 16 | 17 | # Remember not to checkin your GCS keyfile to a repository 18 | # google: 19 | # service: GCS 20 | # project: your_project 21 | # credentials: <%= Rails.root.join("path/to/gcs.keyfile") %> 22 | # bucket: your_own_bucket 23 | 24 | # Use rails credentials:edit to set the Azure Storage secret (as azure_storage:storage_access_key) 25 | # microsoft: 26 | # service: AzureStorage 27 | # storage_account_name: your_account_name 28 | # storage_access_key: <%= Rails.application.credentials.dig(:azure_storage, :storage_access_key) %> 29 | # container: your_container_name 30 | 31 | # mirror: 32 | # service: Mirror 33 | # primary: local 34 | # mirrors: [ amazon, google, microsoft ] 35 | -------------------------------------------------------------------------------- /db/migrate/20150407030922_create_publications.rb: -------------------------------------------------------------------------------- 1 | class CreatePublications < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :publications do |t| 4 | t.integer :owner_id, null: false, index: true 5 | t.string :title, null: false 6 | t.string :description 7 | 8 | t.timestamps null: false 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20150407031014_create_users.rb: -------------------------------------------------------------------------------- 1 | class CreateUsers < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :users do |t| 4 | t.string :email, null: false, unique: true 5 | t.string :password_digest, null: false 6 | t.string :session_token, null: false, unique: true 7 | 8 | t.timestamps null: false 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20150407031117_create_stories.rb: -------------------------------------------------------------------------------- 1 | class CreateStories < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :stories do |t| 4 | t.integer :author_id, null: false, index: true 5 | t.integer :pub_id, null: false, index: true 6 | t.string :title, null: false 7 | t.string :subtitle 8 | t.text :body 9 | t.integer :story_id, index: true 10 | 11 | t.timestamps null: false 12 | end 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /db/migrate/20150407031152_create_tags.rb: -------------------------------------------------------------------------------- 1 | class CreateTags < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :tags do |t| 4 | t.string :label, null: false, unique: true 5 | 6 | t.timestamps null: false 7 | end 8 | end 9 | end 10 | -------------------------------------------------------------------------------- /db/migrate/20150407210923_remove_null_false_from_pub_id.rb: -------------------------------------------------------------------------------- 1 | class RemoveNullFalseFromPubId < ActiveRecord::Migration[7.0] 2 | def change 3 | change_column :stories, :pub_id, :string, null: true, index: true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20150407232751_add_description_to_users.rb: -------------------------------------------------------------------------------- 1 | class AddDescriptionToUsers < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :users, :description, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20150408182531_create_follows.rb: -------------------------------------------------------------------------------- 1 | class CreateFollows < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :follows do |t| 4 | t.integer :followable_id 5 | t.integer :follower_id 6 | t.string :followable_type 7 | 8 | t.timestamps null: false 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20150409212038_add_header_image_to_stories.rb: -------------------------------------------------------------------------------- 1 | class AddHeaderImageToStories < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :stories, :header_image, :text 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20150409224359_add_header_image_to_pubs.rb: -------------------------------------------------------------------------------- 1 | class AddHeaderImageToPubs < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :publications, :header_image, :text 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20150411074919_create_publication_edits.rb: -------------------------------------------------------------------------------- 1 | class CreatePublicationEdits < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :publication_edits do |t| 4 | t.integer :editor_id, null: false, index: true 5 | t.integer :pub_id, null: false, index: true 6 | 7 | t.timestamps null: false 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20150411075008_create_publication_writes.rb: -------------------------------------------------------------------------------- 1 | class CreatePublicationWrites < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :publication_writes do |t| 4 | t.integer :writer_id, null: false, index: true 5 | t.integer :pub_id, null: false, index: true 6 | 7 | t.timestamps null: false 8 | end 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /db/migrate/20150412011132_create_taggings.rb: -------------------------------------------------------------------------------- 1 | class CreateTaggings < ActiveRecord::Migration[7.0] 2 | def change 3 | create_table :taggings do |t| 4 | t.integer :taggable_id, null: false, index: true 5 | t.integer :tag_id, null: false, index: true 6 | t.string :taggable_type, null: false 7 | 8 | t.timestamps null: false 9 | end 10 | end 11 | end 12 | -------------------------------------------------------------------------------- /db/migrate/20150413001413_change_pub_edits_table.rb: -------------------------------------------------------------------------------- 1 | class ChangePubEditsTable < ActiveRecord::Migration[7.0] 2 | def change 3 | 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20150415081536_make_title_null_allowed.rb: -------------------------------------------------------------------------------- 1 | class MakeTitleNullAllowed < ActiveRecord::Migration[7.0] 2 | def change 3 | change_column_null :stories, :title, true 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20150415184559_add_headers_and_icons.rb: -------------------------------------------------------------------------------- 1 | class AddHeadersAndIcons < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :users, :header_image, :text 4 | add_column :users, :icon_image, :text 5 | add_column :publications, :icon_image, :text 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /db/migrate/20150417185017_header_align_column.rb: -------------------------------------------------------------------------------- 1 | class HeaderAlignColumn < ActiveRecord::Migration[7.0] 2 | def change 3 | add_column :publications, :header_align, :string 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20150417185247_default_align_value.rb: -------------------------------------------------------------------------------- 1 | class DefaultAlignValue < ActiveRecord::Migration[7.0] 2 | def change 3 | change_column :publications, :header_align, :string, default: "center" 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20150417191221_remove_default_value.rb: -------------------------------------------------------------------------------- 1 | class RemoveDefaultValue < ActiveRecord::Migration[7.0] 2 | def change 3 | change_column_default(:publications, :header_align, nil) 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /db/migrate/20150417192443_replace_header_align_column.rb: -------------------------------------------------------------------------------- 1 | class ReplaceHeaderAlignColumn < ActiveRecord::Migration[7.0] 2 | def change 3 | remove_column :publications, :header_align 4 | add_column :publications, :header_align, :string 5 | end 6 | end 7 | -------------------------------------------------------------------------------- /db/schema.rb: -------------------------------------------------------------------------------- 1 | # This file is auto-generated from the current state of the database. Instead 2 | # of editing this file, please use the migrations feature of Active Record to 3 | # incrementally modify your database, and then regenerate this schema definition. 4 | # 5 | # This file is the source Rails uses to define your schema when running `bin/rails 6 | # db:schema:load`. When creating a new database, `bin/rails db:schema:load` tends to 7 | # be faster and is potentially less error prone than running all of your 8 | # migrations from scratch. Old migrations may fail to apply correctly if those 9 | # migrations use external dependencies or application code. 10 | # 11 | # It's strongly recommended that you check this file into your version control system. 12 | 13 | ActiveRecord::Schema[7.0].define(version: 2015_04_17_192443) do 14 | # These are extensions that must be enabled in order to support this database 15 | enable_extension "plpgsql" 16 | 17 | create_table "follows", force: :cascade do |t| 18 | t.integer "followable_id" 19 | t.integer "follower_id" 20 | t.string "followable_type" 21 | t.datetime "created_at", null: false 22 | t.datetime "updated_at", null: false 23 | end 24 | 25 | create_table "publication_edits", force: :cascade do |t| 26 | t.integer "editor_id", null: false 27 | t.integer "pub_id", null: false 28 | t.datetime "created_at", null: false 29 | t.datetime "updated_at", null: false 30 | t.index ["editor_id"], name: "index_publication_edits_on_editor_id" 31 | t.index ["pub_id"], name: "index_publication_edits_on_pub_id" 32 | end 33 | 34 | create_table "publication_writes", force: :cascade do |t| 35 | t.integer "writer_id", null: false 36 | t.integer "pub_id", null: false 37 | t.datetime "created_at", null: false 38 | t.datetime "updated_at", null: false 39 | t.index ["pub_id"], name: "index_publication_writes_on_pub_id" 40 | t.index ["writer_id"], name: "index_publication_writes_on_writer_id" 41 | end 42 | 43 | create_table "publications", force: :cascade do |t| 44 | t.integer "owner_id", null: false 45 | t.string "title", null: false 46 | t.string "description" 47 | t.datetime "created_at", null: false 48 | t.datetime "updated_at", null: false 49 | t.text "header_image" 50 | t.text "icon_image" 51 | t.string "header_align" 52 | t.index ["owner_id"], name: "index_publications_on_owner_id" 53 | end 54 | 55 | create_table "stories", force: :cascade do |t| 56 | t.integer "author_id", null: false 57 | t.string "pub_id" 58 | t.string "title" 59 | t.string "subtitle" 60 | t.text "body" 61 | t.integer "story_id" 62 | t.datetime "created_at", null: false 63 | t.datetime "updated_at", null: false 64 | t.text "header_image" 65 | t.index ["author_id"], name: "index_stories_on_author_id" 66 | t.index ["pub_id"], name: "index_stories_on_pub_id" 67 | t.index ["story_id"], name: "index_stories_on_story_id" 68 | end 69 | 70 | create_table "taggings", force: :cascade do |t| 71 | t.integer "taggable_id", null: false 72 | t.integer "tag_id", null: false 73 | t.string "taggable_type", null: false 74 | t.datetime "created_at", null: false 75 | t.datetime "updated_at", null: false 76 | t.index ["tag_id"], name: "index_taggings_on_tag_id" 77 | t.index ["taggable_id"], name: "index_taggings_on_taggable_id" 78 | end 79 | 80 | create_table "tags", force: :cascade do |t| 81 | t.string "label", null: false 82 | t.datetime "created_at", null: false 83 | t.datetime "updated_at", null: false 84 | end 85 | 86 | create_table "users", force: :cascade do |t| 87 | t.string "email", null: false 88 | t.string "password_digest", null: false 89 | t.string "session_token", null: false 90 | t.datetime "created_at", null: false 91 | t.datetime "updated_at", null: false 92 | t.string "description" 93 | t.text "header_image" 94 | t.text "icon_image" 95 | end 96 | 97 | end 98 | -------------------------------------------------------------------------------- /docs/phases/phase1.md: -------------------------------------------------------------------------------- 1 | # Phase 1: User Authentication, Story Creation 2 | 3 | ## Rails 4 | ### Models 5 | * User 6 | * Publication 7 | * Story 8 | 9 | ### Controllers 10 | * UsersController (create, new) 11 | * SessionsController (create, new, destroy) 12 | * PublicationsController (create, new, show) 13 | * StoriesController (create, new, show) 14 | 15 | ### Views 16 | * users/new.html.erb 17 | * users/show.html.erb 18 | * session/new.html.erb 19 | * publications/new.html.erb 20 | * publications/show.html.erb 21 | 22 | ## Backbone 23 | ### Models 24 | 25 | ### Collections 26 | 27 | ### Views 28 | 29 | ## Gems/Libraries 30 | -------------------------------------------------------------------------------- /docs/phases/phase2.md: -------------------------------------------------------------------------------- 1 | # Phase 2: Viewing Publications and Stories 2 | 3 | ## Rails 4 | ### Models 5 | 6 | ### Controllers 7 | Api::PublicationsController (create, destroy, index, show) 8 | Api::UsersController (create, destroy, index, show) 9 | Api::StoriesController (create, destroy, index, show, update) 10 | 11 | ### Views 12 | * pubs/show.json.jbuilder 13 | * users/show.json.jbuilder 14 | 15 | ## Backbone 16 | ### Models 17 | * Publication 18 | * Story 19 | * User 20 | 21 | ### Collections 22 | * Publication 23 | * Story 24 | * User 25 | 26 | ### Views 27 | * PubForm 28 | * PubShow (composite view, contains StoriesIndex subview) 29 | * UserShow (composite view, contains StoriesIndex subview) 30 | * StoriesIndex (composite view, contains StoriesIndexItem subviews) 31 | * StoriesIndexItem 32 | * StoryForm 33 | * StoryShow (composite view, contains StoryForm subview for responses) 34 | * ConfirmPublish 35 | * Your Stories 36 | 37 | ## Gems/Libraries 38 | -------------------------------------------------------------------------------- /docs/phases/phase3.md: -------------------------------------------------------------------------------- 1 | # Phase 3: Editing and Displaying Stories 2 | 3 | ## Rails 4 | ### Models 5 | * Tag 6 | 7 | ### Controllers 8 | Api::TagsController (create, destroy, index, show) 9 | 10 | ### Views 11 | * tags/index.json.jbuilder 12 | 13 | ## Backbone 14 | ### Models 15 | * Tag 16 | 17 | ### Collections 18 | * Tag 19 | 20 | ### Views 21 | * StoryForm 22 | * ConfirmForm 23 | * PubForm 24 | * PubAbout (composite view, contains UsersIndex subviews) 25 | 26 | ## Gems/Libraries 27 | * Filepicker 28 | * TBD 29 | -------------------------------------------------------------------------------- /docs/phases/phase4.md: -------------------------------------------------------------------------------- 1 | # Phase 4: User Feeds 2 | 3 | ## Rails 4 | ### Models 5 | 6 | ### Controllers 7 | Api::StoriesController (feed) 8 | 9 | ### Views 10 | stories/feed.json.jbuilder 11 | 12 | ## Backbone 13 | ### Models 14 | 15 | ### Collections 16 | 17 | ### Views 18 | * HomeShow (composite view, contains StoriesIndex subview) 19 | 20 | ## Gems/Libraries 21 | -------------------------------------------------------------------------------- /docs/phases/phase5.md: -------------------------------------------------------------------------------- 1 | # Phase 5: Searching for Users, Stories and Publications 2 | 3 | ## Rails 4 | ### Models 5 | 6 | ### Controllers 7 | Api::BlogsController (search) 8 | Api::PostsController (search) 9 | 10 | ### Views 11 | 12 | ## Backbone 13 | ### Models 14 | 15 | ### Collections 16 | 17 | ### Views 18 | * StorySearchItem 19 | * UserSearchItem 20 | * PubSearchItem 21 | * SearchShow (composite view, contains StoryIndex, PubIndex, UsersIndex, and TagIndex subviews) 22 | 23 | ## Gems/Libraries 24 | -------------------------------------------------------------------------------- /docs/schema.md: -------------------------------------------------------------------------------- 1 | # Schema Information 2 | 3 | ## publications 4 | column name | data type | details 5 | ------------|-----------|----------------------- 6 | id | integer | not null, primary key 7 | owner_id | integer | not null, foreign key (references users) 8 | title | string | not null 9 | description | string | 10 | 11 | ## users 12 | column name | data type | details 13 | ----------------|-----------|----------------------- 14 | id | integer | not null, primary key 15 | email | string | not null, unique 16 | password_digest | string | not null 17 | session_token | string | not null, unique 18 | 19 | ## followings 20 | column name | data type | details 21 | ----------------|-----------|----------------------- 22 | id | integer | not null, primary key 23 | followable_id | integer | not null, foreign key (references publications or users) 24 | follower_id | integer | not null, foreign key (references users) 25 | followable_type | string | not null 26 | 27 | ## stories 28 | column name | data type | details 29 | ------------|-----------|----------------------- 30 | id | integer | not null, primary key 31 | author_id | integer | not null, foreign key (references users) 32 | pub_id | integer | foreign key (references publications) 33 | title | string | not null 34 | subtitle | string | 35 | body | text | 36 | story_id | integer | foreign key (references stories, if story is a response) 37 | 38 | ## editings 39 | column name | data type | details 40 | ------------|-----------|----------------------- 41 | id | integer | not null, primary key 42 | editor_id | integer | not null (references users) 43 | pub_id | integer | not null (references publications) 44 | 45 | ## contributions 46 | column name | data type | details 47 | ------------|-----------|----------------------- 48 | id | integer | not null, primary key 49 | writer_id | integer | not null (references users) 50 | pub_id | integer | not null (references publications) 51 | 52 | ## tags 53 | column name | data type | details 54 | ------------|-----------|----------------------- 55 | id | integer | not null, primary key 56 | label | string | not null, unique 57 | 58 | ## taggings 59 | column name | data type | details 60 | --------------|-----------|----------------------- 61 | id | integer | not null, primary key 62 | taggable_id | integer | not null, foreign key (references stories or publications) 63 | tag_id | integer | not null, foreign key (references tags) 64 | taggable_type | string | not null 65 | -------------------------------------------------------------------------------- /docs/views.md: -------------------------------------------------------------------------------- 1 | # View Wireframes 2 | 3 | ## Landing Page - Not signed in 4 | ![LP-signed-out] 5 | 6 | ## Landing Page - Signed in 7 | ![LP-signed-in] 8 | 9 | ## New Session / User 10 | ![new-session] 11 | 12 | ## User Show 13 | ![user-show] 14 | 15 | ## User Stories 16 | ![user-stories] 17 | 18 | ## Publication Show 19 | ![pub-show] 20 | 21 | ## Publication About 22 | ![pub-about] 23 | 24 | ## Story Show 25 | ![story-show] 26 | 27 | ## Story Form 28 | ![story-form] 29 | 30 | ## Confirm Publish 31 | ![confirm-publish] 32 | 33 | ## Publication Form 34 | ![pub-form] 35 | 36 | ## Search Results 37 | ![search-results] 38 | 39 | [LP-signed-out]: ./wireframes/LP_signed_out.png 40 | [LP-signed-in]: ./wireframes/LP_signed_in.png 41 | [new-session]: ./wireframes/new_session.png 42 | [user-show]: ./wireframes/user_show.png 43 | [user-stories]: ./wireframes/user_stories.png 44 | [pub-show]: ./wireframes/pub_show.png 45 | [pub-about]: ./wireframes/pub_about.png 46 | [story-show]: ./wireframes/story_show.png 47 | [story-form]: ./wireframes/story_form.png 48 | [confirm-publish]: ./wireframes/confirm_publish.png 49 | [pub-form]: ./wireframes/pub_form.png 50 | [search-results]: ./wireframes/search_results.png 51 | -------------------------------------------------------------------------------- /docs/wireframes/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/docs/wireframes/.DS_Store -------------------------------------------------------------------------------- /docs/wireframes/LP_signed_in.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/docs/wireframes/LP_signed_in.png -------------------------------------------------------------------------------- /docs/wireframes/LP_signed_out.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/docs/wireframes/LP_signed_out.png -------------------------------------------------------------------------------- /docs/wireframes/confirm_publish.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/docs/wireframes/confirm_publish.png -------------------------------------------------------------------------------- /docs/wireframes/new_session.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/docs/wireframes/new_session.png -------------------------------------------------------------------------------- /docs/wireframes/pub_about.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/docs/wireframes/pub_about.png -------------------------------------------------------------------------------- /docs/wireframes/pub_form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/docs/wireframes/pub_form.png -------------------------------------------------------------------------------- /docs/wireframes/pub_show.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/docs/wireframes/pub_show.png -------------------------------------------------------------------------------- /docs/wireframes/search_results.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/docs/wireframes/search_results.png -------------------------------------------------------------------------------- /docs/wireframes/story_form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/docs/wireframes/story_form.png -------------------------------------------------------------------------------- /docs/wireframes/story_show.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/docs/wireframes/story_show.png -------------------------------------------------------------------------------- /docs/wireframes/user_show.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/docs/wireframes/user_show.png -------------------------------------------------------------------------------- /docs/wireframes/user_stories.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/docs/wireframes/user_stories.png -------------------------------------------------------------------------------- /lib/assets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/lib/assets/.keep -------------------------------------------------------------------------------- /lib/tasks/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/lib/tasks/.keep -------------------------------------------------------------------------------- /lib/tasks/delete_everything.rake: -------------------------------------------------------------------------------- 1 | #lib/tasks/delete_everything.rake 2 | 3 | namespace :db do 4 | desc "Drop all tables (except schema_migrations)" 5 | task :delete_everything => :environment do 6 | raise "Cannot run this task in production" if Rails.env.production? 7 | 8 | puts "Dropping all tables (except migrations table)" 9 | ActiveRecord::Base.connection.tables.each do |table| 10 | if table != 'schema_migrations' 11 | query = "DROP TABLE IF EXISTS #{table} CASCADE;" 12 | ActiveRecord::Base.connection.execute(query) 13 | end 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /log/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/log/.keep -------------------------------------------------------------------------------- /npm-debug.log: -------------------------------------------------------------------------------- 1 | 0 info it worked if it ends with ok 2 | 1 verbose cli [ '/opt/local/bin/node', '/opt/local/bin/npm', 'install' ] 3 | 2 info using npm@2.5.0 4 | 3 info using node@v0.12.0 5 | 4 error install Couldn't read dependencies 6 | 5 verbose stack Error: ENOENT, open '/Users/haleyt/Final Project/Large/package.json' 7 | 5 verbose stack at Error (native) 8 | 6 verbose cwd /Users/haleyt/Final Project/Large 9 | 7 error Darwin 13.4.0 10 | 8 error argv "/opt/local/bin/node" "/opt/local/bin/npm" "install" 11 | 9 error node v0.12.0 12 | 10 error npm v2.5.0 13 | 11 error path /Users/haleyt/Final Project/Large/package.json 14 | 12 error code ENOPACKAGEJSON 15 | 13 error errno -2 16 | 14 error package.json ENOENT, open '/Users/haleyt/Final Project/Large/package.json' 17 | 14 error package.json This is most likely not a problem with npm itself. 18 | 14 error package.json npm can't find a package.json file in your current directory. 19 | 15 verbose exit [ -2, true ] 20 | -------------------------------------------------------------------------------- /public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
    60 |
    61 |

    The page you were looking for doesn't exist.

    62 |

    You may have mistyped the address or the page may have moved.

    63 |
    64 |

    If you are the application owner check the logs for more information.

    65 |
    66 | 67 | 68 | -------------------------------------------------------------------------------- /public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
    60 |
    61 |

    The change you wanted was rejected.

    62 |

    Maybe you tried to change something you didn't have access to.

    63 |
    64 |

    If you are the application owner check the logs for more information.

    65 |
    66 | 67 | 68 | -------------------------------------------------------------------------------- /public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
    60 |
    61 |

    We're sorry, but something went wrong.

    62 |
    63 |

    If you are the application owner check the logs for more information.

    64 |
    65 | 66 | 67 | -------------------------------------------------------------------------------- /public/favicon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/public/favicon.ico -------------------------------------------------------------------------------- /public/robots.txt: -------------------------------------------------------------------------------- 1 | # See http://www.robotstxt.org/robotstxt.html for documentation on how to use the robots.txt file 2 | # 3 | # To ban all spiders from the entire site uncomment the next two lines: 4 | # User-agent: * 5 | # Disallow: / 6 | -------------------------------------------------------------------------------- /test/controllers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/test/controllers/.keep -------------------------------------------------------------------------------- /test/controllers/follows_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class FollowsControllerTest < ActionController::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/controllers/publication_edits_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class PublicationEditsControllerTest < ActionController::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/controllers/publication_writes_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class PublicationWritesControllerTest < ActionController::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/controllers/publications_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class PublicationsControllerTest < ActionController::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/controllers/sessions_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class SessionsControllerTest < ActionController::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/controllers/stories_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class StoriesControllerTest < ActionController::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/controllers/users_controller_test.rb: -------------------------------------------------------------------------------- 1 | require 'test_helper' 2 | 3 | class UsersControllerTest < ActionController::TestCase 4 | # test "the truth" do 5 | # assert true 6 | # end 7 | end 8 | -------------------------------------------------------------------------------- /test/fixtures/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/test/fixtures/.keep -------------------------------------------------------------------------------- /test/fixtures/follows.yml: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: follows 4 | # 5 | # id :integer not null, primary key 6 | # followable_id :integer 7 | # follower_id :integer 8 | # followable_type :string 9 | # created_at :datetime not null 10 | # updated_at :datetime not null 11 | # 12 | 13 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 14 | 15 | one: 16 | followable_id: 1 17 | follower_id: 1 18 | followable_type: MyString 19 | 20 | two: 21 | followable_id: 1 22 | follower_id: 1 23 | followable_type: MyString 24 | -------------------------------------------------------------------------------- /test/fixtures/publication_edits.yml: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: publication_edits 4 | # 5 | # id :integer not null, primary key 6 | # editor_id :integer not null 7 | # pub_id :integer not null 8 | # created_at :datetime not null 9 | # updated_at :datetime not null 10 | # 11 | 12 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 13 | 14 | one: 15 | editor_id: 1 16 | pub_id: 1 17 | 18 | two: 19 | editor_id: 1 20 | pub_id: 1 21 | -------------------------------------------------------------------------------- /test/fixtures/publication_writes.yml: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: publication_writes 4 | # 5 | # id :integer not null, primary key 6 | # writer_id :integer not null 7 | # pub_id :integer not null 8 | # created_at :datetime not null 9 | # updated_at :datetime not null 10 | # 11 | 12 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 13 | 14 | one: 15 | writer_id: 1 16 | pub_id: 1 17 | 18 | two: 19 | writer_id: 1 20 | pub_id: 1 21 | -------------------------------------------------------------------------------- /test/fixtures/publications.yml: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: publications 4 | # 5 | # id :integer not null, primary key 6 | # owner_id :integer not null 7 | # title :string not null 8 | # description :string 9 | # created_at :datetime not null 10 | # updated_at :datetime not null 11 | # header_image :text 12 | # icon_image :text 13 | # header_align :string 14 | # 15 | 16 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 17 | 18 | one: 19 | owner_id: 1 20 | title: MyString 21 | description: MyString 22 | 23 | two: 24 | owner_id: 1 25 | title: MyString 26 | description: MyString 27 | -------------------------------------------------------------------------------- /test/fixtures/stories.yml: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: stories 4 | # 5 | # id :integer not null, primary key 6 | # author_id :integer not null 7 | # pub_id :string 8 | # title :string 9 | # subtitle :string 10 | # body :text 11 | # story_id :integer 12 | # created_at :datetime not null 13 | # updated_at :datetime not null 14 | # header_image :text 15 | # 16 | 17 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 18 | 19 | one: 20 | author_id: 1 21 | pub_id: 1 22 | title: MyString 23 | subtitle: MyString 24 | body: MyText 25 | story_id: 1 26 | 27 | two: 28 | author_id: 1 29 | pub_id: 1 30 | title: MyString 31 | subtitle: MyString 32 | body: MyText 33 | story_id: 1 34 | -------------------------------------------------------------------------------- /test/fixtures/taggings.yml: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: taggings 4 | # 5 | # id :integer not null, primary key 6 | # taggable_id :integer not null 7 | # tag_id :integer not null 8 | # taggable_type :string not null 9 | # created_at :datetime not null 10 | # updated_at :datetime not null 11 | # 12 | 13 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 14 | 15 | one: 16 | taggable_id: 1 17 | tag_id: 1 18 | taggable_type: MyString 19 | 20 | two: 21 | taggable_id: 1 22 | tag_id: 1 23 | taggable_type: MyString 24 | -------------------------------------------------------------------------------- /test/fixtures/tags.yml: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: tags 4 | # 5 | # id :integer not null, primary key 6 | # label :string not null 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | 11 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 12 | 13 | one: 14 | label: MyString 15 | 16 | two: 17 | label: MyString 18 | -------------------------------------------------------------------------------- /test/fixtures/users.yml: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: users 4 | # 5 | # id :integer not null, primary key 6 | # email :string not null 7 | # password_digest :string not null 8 | # session_token :string not null 9 | # created_at :datetime not null 10 | # updated_at :datetime not null 11 | # description :string 12 | # header_image :text 13 | # icon_image :text 14 | # 15 | 16 | # Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html 17 | 18 | one: 19 | email: MyString 20 | password_digest: MyString 21 | session_token: MyString 22 | 23 | two: 24 | email: MyString 25 | password_digest: MyString 26 | session_token: MyString 27 | -------------------------------------------------------------------------------- /test/helpers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/test/helpers/.keep -------------------------------------------------------------------------------- /test/integration/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/test/integration/.keep -------------------------------------------------------------------------------- /test/mailers/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/test/mailers/.keep -------------------------------------------------------------------------------- /test/models/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/test/models/.keep -------------------------------------------------------------------------------- /test/models/follow_test.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: follows 4 | # 5 | # id :integer not null, primary key 6 | # followable_id :integer 7 | # follower_id :integer 8 | # followable_type :string 9 | # created_at :datetime not null 10 | # updated_at :datetime not null 11 | # 12 | 13 | require 'test_helper' 14 | 15 | class FollowTest < ActiveSupport::TestCase 16 | # test "the truth" do 17 | # assert true 18 | # end 19 | end 20 | -------------------------------------------------------------------------------- /test/models/publication_edit_test.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: publication_edits 4 | # 5 | # id :integer not null, primary key 6 | # editor_id :integer not null 7 | # pub_id :integer not null 8 | # created_at :datetime not null 9 | # updated_at :datetime not null 10 | # 11 | 12 | require 'test_helper' 13 | 14 | class PublicationEditTest < ActiveSupport::TestCase 15 | # test "the truth" do 16 | # assert true 17 | # end 18 | end 19 | -------------------------------------------------------------------------------- /test/models/publication_test.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: publications 4 | # 5 | # id :integer not null, primary key 6 | # owner_id :integer not null 7 | # title :string not null 8 | # description :string 9 | # created_at :datetime not null 10 | # updated_at :datetime not null 11 | # header_image :text 12 | # icon_image :text 13 | # header_align :string 14 | # 15 | 16 | require 'test_helper' 17 | 18 | class PublicationTest < ActiveSupport::TestCase 19 | # test "the truth" do 20 | # assert true 21 | # end 22 | end 23 | -------------------------------------------------------------------------------- /test/models/publication_write_test.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: publication_writes 4 | # 5 | # id :integer not null, primary key 6 | # writer_id :integer not null 7 | # pub_id :integer not null 8 | # created_at :datetime not null 9 | # updated_at :datetime not null 10 | # 11 | 12 | require 'test_helper' 13 | 14 | class PublicationWriteTest < ActiveSupport::TestCase 15 | # test "the truth" do 16 | # assert true 17 | # end 18 | end 19 | -------------------------------------------------------------------------------- /test/models/story_test.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: stories 4 | # 5 | # id :integer not null, primary key 6 | # author_id :integer not null 7 | # pub_id :string 8 | # title :string 9 | # subtitle :string 10 | # body :text 11 | # story_id :integer 12 | # created_at :datetime not null 13 | # updated_at :datetime not null 14 | # header_image :text 15 | # 16 | 17 | require 'test_helper' 18 | 19 | class StoryTest < ActiveSupport::TestCase 20 | # test "the truth" do 21 | # assert true 22 | # end 23 | end 24 | -------------------------------------------------------------------------------- /test/models/tag_test.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: tags 4 | # 5 | # id :integer not null, primary key 6 | # label :string not null 7 | # created_at :datetime not null 8 | # updated_at :datetime not null 9 | # 10 | 11 | require 'test_helper' 12 | 13 | class TagTest < ActiveSupport::TestCase 14 | # test "the truth" do 15 | # assert true 16 | # end 17 | end 18 | -------------------------------------------------------------------------------- /test/models/tagging_test.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: taggings 4 | # 5 | # id :integer not null, primary key 6 | # taggable_id :integer not null 7 | # tag_id :integer not null 8 | # taggable_type :string not null 9 | # created_at :datetime not null 10 | # updated_at :datetime not null 11 | # 12 | 13 | require 'test_helper' 14 | 15 | class TaggingTest < ActiveSupport::TestCase 16 | # test "the truth" do 17 | # assert true 18 | # end 19 | end 20 | -------------------------------------------------------------------------------- /test/models/user_test.rb: -------------------------------------------------------------------------------- 1 | # == Schema Information 2 | # 3 | # Table name: users 4 | # 5 | # id :integer not null, primary key 6 | # email :string not null 7 | # password_digest :string not null 8 | # session_token :string not null 9 | # created_at :datetime not null 10 | # updated_at :datetime not null 11 | # description :string 12 | # header_image :text 13 | # icon_image :text 14 | # 15 | 16 | require 'test_helper' 17 | 18 | class UserTest < ActiveSupport::TestCase 19 | # test "the truth" do 20 | # assert true 21 | # end 22 | end 23 | -------------------------------------------------------------------------------- /test/test_helper.rb: -------------------------------------------------------------------------------- 1 | ENV['RAILS_ENV'] ||= 'test' 2 | require File.expand_path('../../config/environment', __FILE__) 3 | require 'rails/test_help' 4 | 5 | class ActiveSupport::TestCase 6 | # Setup all fixtures in test/fixtures/*.yml for all tests in alphabetical order. 7 | fixtures :all 8 | 9 | # Add more helper methods to be used by all tests here... 10 | end 11 | -------------------------------------------------------------------------------- /vendor/assets/javascripts/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/vendor/assets/javascripts/.DS_Store -------------------------------------------------------------------------------- /vendor/assets/javascripts/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/vendor/assets/javascripts/.keep -------------------------------------------------------------------------------- /vendor/assets/stylesheets/.keep: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/haleymt/large/9d898a2e1ec6a840cab300e5d6ede9292e571233/vendor/assets/stylesheets/.keep -------------------------------------------------------------------------------- /vendor/assets/stylesheets/themes/bootstrap.css: -------------------------------------------------------------------------------- 1 | .medium-toolbar-arrow-under:after { 2 | top: 60px; 3 | border-color: #428bca transparent transparent transparent; } 4 | 5 | .medium-toolbar-arrow-over:before { 6 | border-color: transparent transparent #428bca transparent; } 7 | 8 | .medium-editor-toolbar { 9 | border: 1px solid #357ebd; 10 | background-color: #428bca; 11 | border-radius: 4px; } 12 | .medium-editor-toolbar li button { 13 | min-width: 60px; 14 | height: 60px; 15 | border: none; 16 | border-right: 1px solid #357ebd; 17 | background-color: transparent; 18 | color: #fff; 19 | box-sizing: border-box; 20 | -webkit-transition: background-color .2s ease-in, color .2s ease-in; 21 | transition: background-color .2s ease-in, color .2s ease-in; } 22 | .medium-editor-toolbar li button:hover { 23 | background-color: #3276b1; 24 | color: #fff; } 25 | .medium-editor-toolbar li .medium-editor-button-first { 26 | border-top-left-radius: 4px; 27 | border-bottom-left-radius: 4px; } 28 | .medium-editor-toolbar li .medium-editor-button-last { 29 | border-right: none; 30 | border-top-right-radius: 4px; 31 | border-bottom-right-radius: 4px; } 32 | .medium-editor-toolbar li .medium-editor-button-active { 33 | background-color: #3276b1; 34 | color: #fff; } 35 | 36 | .medium-editor-toolbar-form { 37 | background: #428bca; 38 | color: #fff; 39 | border-radius: 4px; } 40 | .medium-editor-toolbar-form .medium-editor-toolbar-input { 41 | height: 60px; 42 | background: #428bca; 43 | color: #fff; } 44 | .medium-editor-toolbar-form .medium-editor-toolbar-input::-webkit-input-placeholder { 45 | color: #fff; 46 | color: rgba(255, 255, 255, 0.8); } 47 | .medium-editor-toolbar-form .medium-editor-toolbar-input:-moz-placeholder { 48 | /* Firefox 18- */ 49 | color: #fff; 50 | color: rgba(255, 255, 255, 0.8); } 51 | .medium-editor-toolbar-form .medium-editor-toolbar-input::-moz-placeholder { 52 | /* Firefox 19+ */ 53 | color: #fff; 54 | color: rgba(255, 255, 255, 0.8); } 55 | .medium-editor-toolbar-form .medium-editor-toolbar-input:-ms-input-placeholder { 56 | color: #fff; 57 | color: rgba(255, 255, 255, 0.8); } 58 | .medium-editor-toolbar-form a { 59 | color: #fff; } 60 | 61 | .medium-editor-toolbar-anchor-preview { 62 | background: #428bca; 63 | color: #fff; 64 | border-radius: 4px; } 65 | 66 | .medium-editor-placeholder:after { 67 | color: #357ebd; } 68 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/themes/bootstrap.min.css: -------------------------------------------------------------------------------- 1 | .medium-toolbar-arrow-under:after{top:60px;border-color:#428bca transparent transparent}.medium-toolbar-arrow-over:before{border-color:transparent transparent #428bca}.medium-editor-toolbar{border:1px solid #357ebd;background-color:#428bca;border-radius:4px}.medium-editor-toolbar li button{min-width:60px;height:60px;border:none;border-right:1px solid #357ebd;background-color:transparent;color:#fff;box-sizing:border-box;-webkit-transition:background-color .2s ease-in,color .2s ease-in;transition:background-color .2s ease-in,color .2s ease-in}.medium-editor-toolbar li button:hover{background-color:#3276b1;color:#fff}.medium-editor-toolbar li .medium-editor-button-first{border-top-left-radius:4px;border-bottom-left-radius:4px}.medium-editor-toolbar li .medium-editor-button-last{border-right:none;border-top-right-radius:4px;border-bottom-right-radius:4px}.medium-editor-toolbar li .medium-editor-button-active{background-color:#3276b1;color:#fff}.medium-editor-toolbar-form{background:#428bca;color:#fff;border-radius:4px}.medium-editor-toolbar-form .medium-editor-toolbar-input{height:60px;background:#428bca;color:#fff}.medium-editor-toolbar-form .medium-editor-toolbar-input::-webkit-input-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-moz-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input::-moz-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-ms-input-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form a{color:#fff}.medium-editor-toolbar-anchor-preview{background:#428bca;color:#fff;border-radius:4px}.medium-editor-placeholder:after{color:#357ebd} -------------------------------------------------------------------------------- /vendor/assets/stylesheets/themes/default.css: -------------------------------------------------------------------------------- 1 | .medium-toolbar-arrow-under:after { 2 | top: 35px; 3 | border-color: #242424 transparent transparent transparent; } 4 | 5 | .medium-toolbar-arrow-over:before { 6 | top: -8px; 7 | border-color: transparent transparent #242424 transparent; } 8 | 9 | .medium-editor-toolbar { 10 | margin-top: 10px; 11 | border: 1px solid #000; 12 | background-color: #242424; 13 | background: -webkit-linear-gradient(top, #242424, rgba(36, 36, 36, 0.75)); 14 | background: linear-gradient(to bottom, #242424, rgba(36, 36, 36, 0.75)); 15 | border-radius: 5px; 16 | box-shadow: 0 0 3px #000; } 17 | .medium-editor-toolbar li button { 18 | min-width: 35px; 19 | height: 35px; 20 | border: 0; 21 | border-right: 1px solid #000; 22 | border-left: 1px solid #333; 23 | border-left: 1px solid rgba(255, 255, 255, 0.1); 24 | background-color: #242424; 25 | color: #fff; 26 | background: black; 27 | /*background: -webkit-linear-gradient(top, #242424, rgba(36, 36, 36, 0.89)); 28 | background: linear-gradient(to bottom, #242424, rgba(36, 36, 36, 0.89));*/ 29 | box-shadow: 0 2px 2px rgba(0, 0, 0, 0.3); 30 | -webkit-transition: background-color .2s ease-in; 31 | transition: background-color .2s ease-in; 32 | } 33 | .medium-editor-toolbar li button i { 34 | font-size: 16px; 35 | } 36 | .medium-editor-toolbar li button:hover { 37 | background-color: #000; 38 | color: yellow; } 39 | .medium-editor-toolbar li .medium-editor-button-first { 40 | border-top-left-radius: 5px; 41 | border-bottom-left-radius: 5px; } 42 | .medium-editor-toolbar li .medium-editor-button-last { 43 | border-top-right-radius: 5px; 44 | border-bottom-right-radius: 5px; } 45 | .medium-editor-toolbar li .medium-editor-button-active { 46 | background-color: #000; 47 | color: #fff; 48 | background: -webkit-linear-gradient(top, #242424, rgba(0, 0, 0, 0.89)); 49 | background: linear-gradient(to bottom, #242424, rgba(0, 0, 0, 0.89)); } 50 | 51 | .medium-editor-toolbar-form { 52 | background: #242424; 53 | color: #999; 54 | border-radius: 5px; } 55 | .medium-editor-toolbar-form .medium-editor-toolbar-input { 56 | height: 50px; 57 | background: #242424; 58 | color: #ccc; 59 | box-sizing: border-box; } 60 | .medium-editor-toolbar-form a { 61 | color: #fff; } 62 | 63 | .medium-editor-toolbar-anchor-preview { 64 | background: #242424; 65 | color: #fff; 66 | border-radius: 5px; } 67 | 68 | .medium-editor-placeholder:after { 69 | color: #b3b3b1; } 70 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/themes/default.min.css: -------------------------------------------------------------------------------- 1 | .medium-toolbar-arrow-under:after{top:50px;border-color:#242424 transparent transparent}.medium-toolbar-arrow-over:before{top:-8px;border-color:transparent transparent #242424}.medium-editor-toolbar{border:1px solid #000;background:-webkit-linear-gradient(top,#242424,rgba(36,36,36,.75));background:linear-gradient(to bottom,#242424,rgba(36,36,36,.75));border-radius:5px;box-shadow:0 0 3px #000}.medium-editor-toolbar li button{min-width:50px;height:50px;border:0;border-right:1px solid #000;border-left:1px solid #333;border-left:1px solid rgba(255,255,255,.1);color:#fff;background:-webkit-linear-gradient(top,#242424,rgba(36,36,36,.89));background:linear-gradient(to bottom,#242424,rgba(36,36,36,.89));box-shadow:0 2px 2px rgba(0,0,0,.3);-webkit-transition:background-color .2s ease-in;transition:background-color .2s ease-in}.medium-editor-toolbar li button:hover{background-color:#000;color:#ff0}.medium-editor-toolbar li .medium-editor-button-first{border-top-left-radius:5px;border-bottom-left-radius:5px}.medium-editor-toolbar li .medium-editor-button-last{border-top-right-radius:5px;border-bottom-right-radius:5px}.medium-editor-toolbar li .medium-editor-button-active{color:#fff;background:-webkit-linear-gradient(top,#242424,rgba(0,0,0,.89));background:linear-gradient(to bottom,#242424,rgba(0,0,0,.89))}.medium-editor-toolbar-form{background:#242424;color:#999;border-radius:5px}.medium-editor-toolbar-form .medium-editor-toolbar-input{height:50px;background:#242424;color:#ccc;box-sizing:border-box}.medium-editor-toolbar-form a{color:#fff}.medium-editor-toolbar-anchor-preview{background:#242424;color:#fff;border-radius:5px}.medium-editor-placeholder:after{color:#b3b3b1} -------------------------------------------------------------------------------- /vendor/assets/stylesheets/themes/flat.css: -------------------------------------------------------------------------------- 1 | .medium-toolbar-arrow-under:after { 2 | top: 60px; 3 | border-color: #57ad68 transparent transparent transparent; } 4 | 5 | .medium-toolbar-arrow-over:before { 6 | top: -8px; 7 | border-color: transparent transparent #57ad68 transparent; } 8 | 9 | .medium-editor-toolbar { 10 | background-color: #57ad68; } 11 | .medium-editor-toolbar li { 12 | padding: 0; } 13 | .medium-editor-toolbar li button { 14 | min-width: 60px; 15 | height: 60px; 16 | border: none; 17 | border-right: 1px solid #9ccea6; 18 | background-color: transparent; 19 | color: #fff; 20 | -webkit-transition: background-color .2s ease-in, color .2s ease-in; 21 | transition: background-color .2s ease-in, color .2s ease-in; } 22 | .medium-editor-toolbar li button:hover { 23 | background-color: #346a3f; 24 | color: #fff; } 25 | .medium-editor-toolbar li .medium-editor-button-active { 26 | background-color: #23482a; 27 | color: #fff; } 28 | .medium-editor-toolbar li .medium-editor-button-last { 29 | border-right: none; } 30 | 31 | .medium-editor-toolbar-form .medium-editor-toolbar-input { 32 | height: 60px; 33 | background: #57ad68; 34 | color: #fff; } 35 | .medium-editor-toolbar-form .medium-editor-toolbar-input::-webkit-input-placeholder { 36 | color: #fff; 37 | color: rgba(255, 255, 255, 0.8); } 38 | .medium-editor-toolbar-form .medium-editor-toolbar-input:-moz-placeholder { 39 | /* Firefox 18- */ 40 | color: #fff; 41 | color: rgba(255, 255, 255, 0.8); } 42 | .medium-editor-toolbar-form .medium-editor-toolbar-input::-moz-placeholder { 43 | /* Firefox 19+ */ 44 | color: #fff; 45 | color: rgba(255, 255, 255, 0.8); } 46 | .medium-editor-toolbar-form .medium-editor-toolbar-input:-ms-input-placeholder { 47 | color: #fff; 48 | color: rgba(255, 255, 255, 0.8); } 49 | .medium-editor-toolbar-form a { 50 | color: #fff; } 51 | 52 | .medium-editor-toolbar-anchor-preview { 53 | background: #57ad68; 54 | color: #fff; } 55 | 56 | .medium-editor-placeholder:after { 57 | color: #fff; } 58 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/themes/flat.min.css: -------------------------------------------------------------------------------- 1 | .medium-toolbar-arrow-under:after{top:60px;border-color:#57ad68 transparent transparent}.medium-toolbar-arrow-over:before{top:-8px;border-color:transparent transparent #57ad68}.medium-editor-toolbar{background-color:#57ad68}.medium-editor-toolbar li{padding:0}.medium-editor-toolbar li button{min-width:60px;height:60px;border:none;border-right:1px solid #9ccea6;background-color:transparent;color:#fff;-webkit-transition:background-color .2s ease-in,color .2s ease-in;transition:background-color .2s ease-in,color .2s ease-in}.medium-editor-toolbar li button:hover{background-color:#346a3f;color:#fff}.medium-editor-toolbar li .medium-editor-button-active{background-color:#23482a;color:#fff}.medium-editor-toolbar li .medium-editor-button-last{border-right:none}.medium-editor-toolbar-form .medium-editor-toolbar-input{height:60px;background:#57ad68;color:#fff}.medium-editor-toolbar-form .medium-editor-toolbar-input::-webkit-input-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-moz-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input::-moz-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-toolbar-form .medium-editor-toolbar-input:-ms-input-placeholder{color:#fff;color:rgba(255,255,255,.8)}.medium-editor-placeholder:after,.medium-editor-toolbar-form a{color:#fff}.medium-editor-toolbar-anchor-preview{background:#57ad68;color:#fff} -------------------------------------------------------------------------------- /vendor/assets/stylesheets/themes/mani.css: -------------------------------------------------------------------------------- 1 | .medium-toolbar-arrow-under:after, .medium-toolbar-arrow-over:before { 2 | display: none; } 3 | 4 | .medium-editor-toolbar { 5 | border: 1px solid #cdd6e0; 6 | background-color: #dee7f0; 7 | background-color: rgba(222, 231, 240, 0.95); 8 | background: -webkit-linear-gradient(top, #dee7f0, #ffffff); 9 | background: linear-gradient(to bottom, #dee7f0, #ffffff); 10 | border-radius: 2px; 11 | box-shadow: 0 2px 6px rgba(0, 0, 0, 0.45); } 12 | .medium-editor-toolbar li button { 13 | min-width: 50px; 14 | height: 50px; 15 | border: none; 16 | border-right: 1px solid #cdd6e0; 17 | background-color: transparent; 18 | color: #40648a; 19 | -webkit-transition: background-color .2s ease-in, color .2s ease-in; 20 | transition: background-color .2s ease-in, color .2s ease-in; } 21 | .medium-editor-toolbar li button:hover { 22 | background-color: #5c90c7; 23 | background-color: rgba(92, 144, 199, 0.45); 24 | color: #fff; } 25 | .medium-editor-toolbar li .medium-editor-button-first { 26 | border-top-left-radius: 2px; 27 | border-bottom-left-radius: 2px; } 28 | .medium-editor-toolbar li .medium-editor-button-last { 29 | border-top-right-radius: 2px; 30 | border-bottom-right-radius: 2px; } 31 | .medium-editor-toolbar li .medium-editor-button-active { 32 | background-color: #5c90c7; 33 | background-color: rgba(92, 144, 199, 0.45); 34 | color: #000; 35 | background: -webkit-linear-gradient(top, #dee7f0, rgba(0, 0, 0, 0.1)); 36 | background: linear-gradient(to bottom, #dee7f0, rgba(0, 0, 0, 0.1)); } 37 | 38 | .medium-editor-toolbar-form { 39 | background: #dee7f0; 40 | color: #999; 41 | border-radius: 2px; } 42 | .medium-editor-toolbar-form .medium-editor-toolbar-input { 43 | height: 50px; 44 | background: #dee7f0; 45 | color: #40648a; 46 | box-sizing: border-box; } 47 | .medium-editor-toolbar-form a { 48 | color: #40648a; } 49 | 50 | .medium-editor-toolbar-anchor-preview { 51 | background: #dee7f0; 52 | color: #40648a; 53 | border-radius: 2px; } 54 | 55 | .medium-editor-placeholder:after { 56 | color: #cdd6e0; } 57 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/themes/mani.min.css: -------------------------------------------------------------------------------- 1 | .medium-toolbar-arrow-over:before,.medium-toolbar-arrow-under:after{display:none}.medium-editor-toolbar{border:1px solid #cdd6e0;background:-webkit-linear-gradient(top,#dee7f0,#fff);background:linear-gradient(to bottom,#dee7f0,#fff);border-radius:2px;box-shadow:0 2px 6px rgba(0,0,0,.45)}.medium-editor-toolbar li button{min-width:50px;height:50px;border:none;border-right:1px solid #cdd6e0;background-color:transparent;color:#40648a;-webkit-transition:background-color .2s ease-in,color .2s ease-in;transition:background-color .2s ease-in,color .2s ease-in}.medium-editor-toolbar li button:hover{background-color:#5c90c7;background-color:rgba(92,144,199,.45);color:#fff}.medium-editor-toolbar li .medium-editor-button-first{border-top-left-radius:2px;border-bottom-left-radius:2px}.medium-editor-toolbar li .medium-editor-button-last{border-top-right-radius:2px;border-bottom-right-radius:2px}.medium-editor-toolbar li .medium-editor-button-active{color:#000;background:-webkit-linear-gradient(top,#dee7f0,rgba(0,0,0,.1));background:linear-gradient(to bottom,#dee7f0,rgba(0,0,0,.1))}.medium-editor-toolbar-form{background:#dee7f0;color:#999;border-radius:2px}.medium-editor-toolbar-form .medium-editor-toolbar-input{height:50px;background:#dee7f0;color:#40648a;box-sizing:border-box}.medium-editor-toolbar-form a{color:#40648a}.medium-editor-toolbar-anchor-preview{background:#dee7f0;color:#40648a;border-radius:2px}.medium-editor-placeholder:after{color:#cdd6e0} -------------------------------------------------------------------------------- /vendor/assets/stylesheets/themes/roman.css: -------------------------------------------------------------------------------- 1 | .medium-toolbar-arrow-under:after, .medium-toolbar-arrow-over:before { 2 | display: none; } 3 | 4 | .medium-editor-toolbar { 5 | background-color: #fff; 6 | background-color: rgba(255, 255, 255, 0.95); 7 | border-radius: 5px; 8 | box-shadow: 0 2px 6px rgba(0, 0, 0, 0.45); } 9 | .medium-editor-toolbar li button { 10 | min-width: 50px; 11 | height: 50px; 12 | border: none; 13 | border-right: 1px solid #a8a8a8; 14 | background-color: transparent; 15 | color: #889aac; 16 | box-shadow: inset 0 0 3px #f8f8e6; 17 | background: -webkit-linear-gradient(bottom, #fff, rgba(0, 0, 0, 0.1)); 18 | background: linear-gradient(to top, #fff, rgba(0, 0, 0, 0.1)); 19 | text-shadow: 1px 4px 6px #def, 0 0 0 #000, 1px 4px 6px #def; 20 | -webkit-transition: background-color .2s ease-in; 21 | transition: background-color .2s ease-in; } 22 | .medium-editor-toolbar li button:hover { 23 | background-color: #fff; 24 | color: #000; 25 | color: rgba(0, 0, 0, 0.8); } 26 | .medium-editor-toolbar li .medium-editor-button-first { 27 | border-top-left-radius: 5px; 28 | border-bottom-left-radius: 5px; } 29 | .medium-editor-toolbar li .medium-editor-button-last { 30 | border-top-right-radius: 5px; 31 | border-bottom-right-radius: 5px; } 32 | .medium-editor-toolbar li .medium-editor-button-active { 33 | background-color: #ccc; 34 | color: #000; 35 | color: rgba(0, 0, 0, 0.8); 36 | background: -webkit-linear-gradient(top, #fff, rgba(0, 0, 0, 0.2)); 37 | background: linear-gradient(to bottom, #fff, rgba(0, 0, 0, 0.2)); } 38 | 39 | .medium-editor-toolbar-form { 40 | background: #fff; 41 | color: #999; 42 | border-radius: 5px; } 43 | .medium-editor-toolbar-form .medium-editor-toolbar-input { 44 | margin: 0; 45 | height: 50px; 46 | background: #fff; 47 | color: #a8a8a8; } 48 | .medium-editor-toolbar-form a { 49 | color: #889aac; } 50 | 51 | .medium-editor-toolbar-anchor-preview { 52 | background: #fff; 53 | color: #889aac; 54 | border-radius: 5px; } 55 | 56 | .medium-editor-placeholder:after { 57 | color: #a8a8a8; } 58 | -------------------------------------------------------------------------------- /vendor/assets/stylesheets/themes/roman.min.css: -------------------------------------------------------------------------------- 1 | .medium-toolbar-arrow-over:before,.medium-toolbar-arrow-under:after{display:none}.medium-editor-toolbar{background-color:#fff;background-color:rgba(255,255,255,.95);border-radius:5px;box-shadow:0 2px 6px rgba(0,0,0,.45)}.medium-editor-toolbar li button{min-width:50px;height:50px;border:none;border-right:1px solid #a8a8a8;color:#889aac;box-shadow:inset 0 0 3px #f8f8e6;background:-webkit-linear-gradient(bottom,#fff,rgba(0,0,0,.1));background:linear-gradient(to top,#fff,rgba(0,0,0,.1));text-shadow:1px 4px 6px #def,0 0 0 #000,1px 4px 6px #def;-webkit-transition:background-color .2s ease-in;transition:background-color .2s ease-in}.medium-editor-toolbar li button:hover{background-color:#fff;color:#000;color:rgba(0,0,0,.8)}.medium-editor-toolbar li .medium-editor-button-first{border-top-left-radius:5px;border-bottom-left-radius:5px}.medium-editor-toolbar li .medium-editor-button-last{border-top-right-radius:5px;border-bottom-right-radius:5px}.medium-editor-toolbar li .medium-editor-button-active{color:#000;color:rgba(0,0,0,.8);background:-webkit-linear-gradient(top,#fff,rgba(0,0,0,.2));background:linear-gradient(to bottom,#fff,rgba(0,0,0,.2))}.medium-editor-toolbar-form{background:#fff;color:#999;border-radius:5px}.medium-editor-toolbar-form .medium-editor-toolbar-input{margin:0;height:50px;background:#fff;color:#a8a8a8}.medium-editor-toolbar-form a{color:#889aac}.medium-editor-toolbar-anchor-preview{background:#fff;color:#889aac;border-radius:5px}.medium-editor-placeholder:after{color:#a8a8a8} --------------------------------------------------------------------------------