mirror of
https://github.com/indentlabs/notebook.git
synced 2025-10-26 11:19:22 +00:00
Merge branch 'master' into thredded
Conflicts: db/schema.rb
This commit is contained in:
commit
577de5f447
65
app.json
Normal file
65
app.json
Normal file
@ -0,0 +1,65 @@
|
||||
{
|
||||
"name": "notebook",
|
||||
"scripts": {
|
||||
},
|
||||
"env": {
|
||||
"AWS_ACCESS_KEY_ID": {
|
||||
"required": true
|
||||
},
|
||||
"AWS_REGION": {
|
||||
"required": true
|
||||
},
|
||||
"AWS_SECRET_ACCESS_KEY": {
|
||||
"required": true
|
||||
},
|
||||
"GOOGLE_TRANSLATE_API_KEY": {
|
||||
"required": true
|
||||
},
|
||||
"HEROKU_POSTGRESQL_BROWN_URL": {
|
||||
"required": true
|
||||
},
|
||||
"LANG": {
|
||||
"required": true
|
||||
},
|
||||
"LOG_LEVEL": {
|
||||
"required": true
|
||||
},
|
||||
"RACK_ENV": {
|
||||
"required": true
|
||||
},
|
||||
"RAILS_ENV": {
|
||||
"required": true
|
||||
},
|
||||
"RAILS_SERVE_STATIC_FILES": {
|
||||
"required": true
|
||||
},
|
||||
"RUBY_GC_HEAP_GROWTH_FACTOR": {
|
||||
"required": true
|
||||
},
|
||||
"S3_BUCKET_NAME": {
|
||||
"required": true
|
||||
},
|
||||
"SECRET_KEY_BASE": {
|
||||
"required": true
|
||||
},
|
||||
"SECRET_TOKEN": {
|
||||
"required": true
|
||||
},
|
||||
"STRIPE_API_KEY": {
|
||||
"required": true
|
||||
},
|
||||
"STRIPE_PUBLISHABLE_KEY": {
|
||||
"required": true
|
||||
}
|
||||
},
|
||||
"formation": {
|
||||
},
|
||||
"addons": [
|
||||
"heroku-postgresql"
|
||||
],
|
||||
"buildpacks": [
|
||||
{
|
||||
"url": "heroku/ruby"
|
||||
}
|
||||
]
|
||||
}
|
||||
BIN
app/assets/images/card-headers/floras.jpg
Normal file
BIN
app/assets/images/card-headers/floras.jpg
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 407 KiB |
3
app/assets/javascripts/floras.coffee
Normal file
3
app/assets/javascripts/floras.coffee
Normal file
@ -0,0 +1,3 @@
|
||||
# Place all the behaviors and hooks related to the matching controller here.
|
||||
# All this logic will automatically be available in application.js.
|
||||
# You can use CoffeeScript in this file: http://coffeescript.org/
|
||||
3
app/assets/stylesheets/floras.scss
Normal file
3
app/assets/stylesheets/floras.scss
Normal file
@ -0,0 +1,3 @@
|
||||
// Place all the styles related to the Floras controller here.
|
||||
// They will automatically be included in application.css.
|
||||
// You can use Sass (SCSS) here: http://sass-lang.com/
|
||||
@ -33,13 +33,13 @@ class ContentController < ApplicationController
|
||||
'content_type': content_type.name,
|
||||
'content_owner': current_user.present? && current_user.id == @content.user_id,
|
||||
'logged_in_user': current_user.present?
|
||||
})
|
||||
}) if Rails.env.production?
|
||||
else
|
||||
Mixpanel::Tracker.new(Rails.application.config.mixpanel_token).track(current_user.id, 'viewed recently-modified content', {
|
||||
'content_type': content_type.name,
|
||||
'content_owner': current_user.present? && current_user.id == @content.user_id,
|
||||
'logged_in_user': current_user.present?
|
||||
})
|
||||
}) if Rails.env.production?
|
||||
end
|
||||
end
|
||||
|
||||
@ -94,7 +94,7 @@ class ContentController < ApplicationController
|
||||
|
||||
Mixpanel::Tracker.new(Rails.application.config.mixpanel_token).track(current_user.id, 'created content', {
|
||||
'content_type': content_type.name
|
||||
})
|
||||
}) if Rails.env.production?
|
||||
|
||||
if @content.save
|
||||
if params.key? 'image_uploads'
|
||||
@ -117,7 +117,7 @@ class ContentController < ApplicationController
|
||||
|
||||
Mixpanel::Tracker.new(Rails.application.config.mixpanel_token).track(current_user.id, 'updated content', {
|
||||
'content_type': content_type.name
|
||||
})
|
||||
}) if Rails.env.production?
|
||||
|
||||
if params.key? 'image_uploads'
|
||||
upload_files params['image_uploads'], content_type.name, @content.id
|
||||
@ -156,7 +156,7 @@ class ContentController < ApplicationController
|
||||
'content_type': content_type,
|
||||
'image_size_kb': image_size_kb,
|
||||
'first five images': current_user.image_uploads.count <= 5
|
||||
})
|
||||
}) if Rails.env.production?
|
||||
end
|
||||
end
|
||||
|
||||
@ -170,7 +170,7 @@ class ContentController < ApplicationController
|
||||
|
||||
Mixpanel::Tracker.new(Rails.application.config.mixpanel_token).track(current_user.id, 'deleted content', {
|
||||
'content_type': content_type.name
|
||||
})
|
||||
}) if Rails.env.production?
|
||||
|
||||
@content.destroy
|
||||
|
||||
|
||||
@ -4,14 +4,14 @@ class ExportController < ApplicationController
|
||||
def index
|
||||
Mixpanel::Tracker.new(Rails.application.config.mixpanel_token).track(current_user.id, 'viewed export page', {
|
||||
'content count': current_user.content_count
|
||||
})
|
||||
}) if Rails.env.production?
|
||||
end
|
||||
|
||||
def report_to_mixpanel format, scope
|
||||
Mixpanel::Tracker.new(Rails.application.config.mixpanel_token).track(current_user.id, 'exported content', {
|
||||
'export format': format,
|
||||
'scope': scope
|
||||
})
|
||||
}) if Rails.env.production?
|
||||
end
|
||||
|
||||
# Formats
|
||||
|
||||
25
app/controllers/floras_controller.rb
Normal file
25
app/controllers/floras_controller.rb
Normal file
@ -0,0 +1,25 @@
|
||||
class FlorasController < ContentController
|
||||
private
|
||||
|
||||
def content_params
|
||||
params.require(:flora).permit(content_param_list)
|
||||
end
|
||||
|
||||
def content_param_list
|
||||
%i(
|
||||
name description aliases universe_id
|
||||
order family genus
|
||||
colorings size smell taste
|
||||
fruits seeds nuts berries medicinal_purposes
|
||||
reproduction seasonality
|
||||
privacy
|
||||
notes private_notes
|
||||
) + [
|
||||
custom_attribute_values: [:name, :value],
|
||||
flora_relationships_attributes: [:id, :related_flora_id, :_destroy],
|
||||
flora_magical_effects_attributes: [:id, :magic_id, :_destroy],
|
||||
flora_locations_attributes: [:id, :location_id, :_destroy],
|
||||
flora_eaten_by_attributes: [:id, :creature_id, :_destroy],
|
||||
]
|
||||
end
|
||||
end
|
||||
@ -28,7 +28,7 @@ class ImageUploadController < ApplicationController
|
||||
|
||||
Mixpanel::Tracker.new(Rails.application.config.mixpanel_token).track(current_user.id, 'deleted image', {
|
||||
'image_size_kb': reclaimed_space_kb
|
||||
})
|
||||
}) if Rails.env.production?
|
||||
|
||||
render json: { success: result }, status: 200
|
||||
end
|
||||
|
||||
@ -7,7 +7,7 @@ class SubscriptionsController < ApplicationController
|
||||
Mixpanel::Tracker.new(Rails.application.config.mixpanel_token).track(current_user.id, 'viewed billing page', {
|
||||
'current billing plan': current_user.selected_billing_plan_id,
|
||||
'content count': current_user.content_count
|
||||
})
|
||||
}) if Rails.env.production?
|
||||
|
||||
# We only support a single billing plan right now, so just grab the first one. If they don't have an active plan,
|
||||
# we also treat them as if they have a Starter plan.
|
||||
@ -163,7 +163,7 @@ class SubscriptionsController < ApplicationController
|
||||
Mixpanel::Tracker.new(Rails.application.config.mixpanel_token).track(current_user.id, 'viewed payment method page', {
|
||||
'current billing plan': current_user.selected_billing_plan_id,
|
||||
'content count': current_user.content_count
|
||||
})
|
||||
}) if Rails.env.production?
|
||||
end
|
||||
|
||||
def information_change
|
||||
@ -300,7 +300,7 @@ class SubscriptionsController < ApplicationController
|
||||
end
|
||||
|
||||
def stripe_webhook
|
||||
Mixpanel::Tracker.new(Rails.application.config.mixpanel_token).track(current_user.id, 'stripe webhook')
|
||||
Mixpanel::Tracker.new(Rails.application.config.mixpanel_token).track(current_user.id, 'stripe webhook') if Rails.env.production?
|
||||
#todo handle webhooks
|
||||
end
|
||||
|
||||
|
||||
@ -1,4 +1,19 @@
|
||||
class UniversesController < ContentController
|
||||
|
||||
# TODO: pull list of content types out from some centralized list somewhere
|
||||
[
|
||||
:characters, :locations, :items, :creatures, :races, :religions, :groups, :magics, :languages, :floras, :scenes
|
||||
].each do |content_type_name|
|
||||
define_method content_type_name do
|
||||
@content_type = content_type_name.to_s.singularize.capitalize.constantize
|
||||
|
||||
@universe = Universe.find(params[:id])
|
||||
@content_list = @universe.send(content_type_name).is_public.order(:name)
|
||||
|
||||
render :content_list
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def content_params
|
||||
|
||||
@ -8,6 +8,6 @@ class UsersController < ApplicationController
|
||||
|
||||
Mixpanel::Tracker.new(Rails.application.config.mixpanel_token).track(@user.id, 'viewed profile', {
|
||||
'sharing any content': @user.public_content_count != 0
|
||||
})
|
||||
}) if Rails.env.production?
|
||||
end
|
||||
end
|
||||
|
||||
2
app/helpers/floras_helper.rb
Normal file
2
app/helpers/floras_helper.rb
Normal file
@ -0,0 +1,2 @@
|
||||
module FlorasHelper
|
||||
end
|
||||
@ -17,6 +17,7 @@ module HasContent
|
||||
has_many :magics
|
||||
has_many :languages
|
||||
has_many :groups
|
||||
has_many :floras
|
||||
|
||||
# Collective content types
|
||||
has_many :scenes
|
||||
|
||||
8
app/models/content_groupers/flora_eaten_by.rb
Normal file
8
app/models/content_groupers/flora_eaten_by.rb
Normal file
@ -0,0 +1,8 @@
|
||||
class FloraEatenBy < ActiveRecord::Base
|
||||
include HasContentLinking
|
||||
|
||||
belongs_to :user
|
||||
|
||||
belongs_to :flora
|
||||
belongs_to :creature
|
||||
end
|
||||
8
app/models/content_groupers/flora_location.rb
Normal file
8
app/models/content_groupers/flora_location.rb
Normal file
@ -0,0 +1,8 @@
|
||||
class FloraLocation < ActiveRecord::Base
|
||||
include HasContentLinking
|
||||
|
||||
belongs_to :user
|
||||
|
||||
belongs_to :flora
|
||||
belongs_to :location
|
||||
end
|
||||
8
app/models/content_groupers/flora_magical_effect.rb
Normal file
8
app/models/content_groupers/flora_magical_effect.rb
Normal file
@ -0,0 +1,8 @@
|
||||
class FloraMagicalEffect < ActiveRecord::Base
|
||||
include HasContentLinking
|
||||
|
||||
belongs_to :user
|
||||
|
||||
belongs_to :flora
|
||||
belongs_to :magic, class_name: 'Magic'
|
||||
end
|
||||
21
app/models/content_groupers/flora_relationship.rb
Normal file
21
app/models/content_groupers/flora_relationship.rb
Normal file
@ -0,0 +1,21 @@
|
||||
class FloraRelationship < ActiveRecord::Base
|
||||
include HasContentLinking
|
||||
LINK_TYPE = :two_way
|
||||
|
||||
belongs_to :user
|
||||
|
||||
belongs_to :flora
|
||||
belongs_to :related_flora, class_name: 'Flora'
|
||||
|
||||
after_create do
|
||||
self.reciprocate relation: :flora_relationships, parent_object_ref: :flora, added_object_ref: :related_flora
|
||||
end
|
||||
|
||||
after_destroy do
|
||||
# This is a two-way relation, so we should also delete the reverse association
|
||||
this_object = Flora.find_by(id: self.flora_id)
|
||||
other_object = Flora.find_by(id: self.related_flora_id)
|
||||
|
||||
other_object.related_floras.delete this_object
|
||||
end
|
||||
end
|
||||
38
app/models/content_types/flora.rb
Normal file
38
app/models/content_types/flora.rb
Normal file
@ -0,0 +1,38 @@
|
||||
class Flora < ActiveRecord::Base
|
||||
validates :name, presence: true
|
||||
|
||||
belongs_to :user
|
||||
validates :user_id, presence: true
|
||||
|
||||
include BelongsToUniverse
|
||||
|
||||
include HasAttributes
|
||||
include HasPrivacy
|
||||
include HasContentGroupers
|
||||
include HasImageUploads
|
||||
include HasChangelog
|
||||
|
||||
include Serendipitous::Concern
|
||||
|
||||
include Authority::Abilities
|
||||
self.authorizer_name = 'ExtendedContentAuthorizer'
|
||||
|
||||
relates :related_floras, with: :flora_relationships
|
||||
relates :magics, with: :flora_magical_effects
|
||||
relates :locations, with: :flora_locations
|
||||
relates :creatures, with: :flora_eaten_by
|
||||
|
||||
scope :is_public, -> { eager_load(:universe).where('floras.privacy = ? OR universes.privacy = ?', 'public', 'public') }
|
||||
|
||||
def self.content_name
|
||||
'flora'
|
||||
end
|
||||
|
||||
def self.color
|
||||
'text-lighten-3 lighten-3 teal'
|
||||
end
|
||||
|
||||
def self.icon
|
||||
'local_florist'
|
||||
end
|
||||
end
|
||||
@ -31,6 +31,7 @@ class Universe < ActiveRecord::Base
|
||||
has_many :religions
|
||||
has_many :magics
|
||||
has_many :languages
|
||||
has_many :floras
|
||||
|
||||
has_many :scenes
|
||||
has_many :groups
|
||||
|
||||
@ -30,7 +30,11 @@
|
||||
<%= content_type_class.icon %>
|
||||
</i>
|
||||
<% end %>
|
||||
<%= content_type.to_s.pluralize.titleize %>
|
||||
<% if defined?(@content) && @content.is_a?(Universe) && content_type != :universe %>
|
||||
<%= link_to content_type.to_s.pluralize.titleize, send("#{content_type.to_s.pluralize}_universe_path", { id: @content.id }), class: "#{content_type_class.color}-text" %>
|
||||
<% else %>
|
||||
<%= content_type.to_s.pluralize.titleize %>
|
||||
<% end %>
|
||||
<i class="material-icons right">close</i>
|
||||
</span>
|
||||
<% if content_list.any? %>
|
||||
@ -54,6 +58,16 @@
|
||||
</tr>
|
||||
<% end %>
|
||||
</table>
|
||||
<div class="center" style="margin-top: 30px">
|
||||
<% if defined?(@content) && @content.is_a?(Universe) && content_type != :universe %>
|
||||
<%= link_to "Browse #{content_type.to_s.pluralize}", send("#{content_type.to_s.pluralize}_universe_path", { id: @content.id }), class: "btn #{content_type_class.color} lighten-1" %>
|
||||
<% else %>
|
||||
<div class="center">
|
||||
<% button_text = content_list.any? ? "Create another #{content_type}" : "Create one" %>
|
||||
<%= link_to button_text, new_polymorphic_path(content_type), class: "btn #{content_type_class.color}" if current_user %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<% elsif content_list.empty? %>
|
||||
<div class="row">
|
||||
<div class="col s4">
|
||||
|
||||
@ -0,0 +1,38 @@
|
||||
<%=
|
||||
render partial: 'content/contexts/relation', locals: {
|
||||
content_type: Flora,
|
||||
content: content,
|
||||
relation_class: FloraEatenBy,
|
||||
relation_class_id: :creature_id,
|
||||
relation_text: :eats
|
||||
}
|
||||
%>
|
||||
|
||||
<% @references.each do |content_type, relations| %>
|
||||
<% next unless relations.any? %>
|
||||
<%
|
||||
card_title = if relations.count == 1
|
||||
if relations.first.first.include? '<plural>'
|
||||
relations.first.first
|
||||
else
|
||||
[
|
||||
relations.first.first,
|
||||
' ',
|
||||
pluralize(relations.count, "#{content_type.to_s.singularize}")
|
||||
].join
|
||||
end
|
||||
else
|
||||
[
|
||||
'Related to ',
|
||||
pluralize(relations.count, "other #{content_type.to_s.singularize}")
|
||||
].join
|
||||
end
|
||||
%>
|
||||
<div class="col s12 m6 l4">
|
||||
<%= render partial: 'content/cards/content_relation_list', locals: {
|
||||
content_type: content_type,
|
||||
relations: relations,
|
||||
card_title: card_title
|
||||
} %>
|
||||
</div>
|
||||
<% end %>
|
||||
@ -57,6 +57,16 @@
|
||||
}
|
||||
%>
|
||||
|
||||
<%=
|
||||
render partial: 'content/contexts/relation', locals: {
|
||||
content_type: Flora,
|
||||
content: content,
|
||||
relation_class: FloraLocation,
|
||||
relation_class_id: :location_id,
|
||||
relation_text: '<plural> found here'
|
||||
}
|
||||
%>
|
||||
|
||||
<% scenes = SceneLocationship.where(scene_location_id: content.id).map(&:scene).compact.select { |content| content && content.readable_by?(current_user || User.new) } %>
|
||||
<% if scenes.any? %>
|
||||
<div class="col s12 m6 l4">
|
||||
|
||||
9
app/views/content/contexts/_magic.html.erb
Normal file
9
app/views/content/contexts/_magic.html.erb
Normal file
@ -0,0 +1,9 @@
|
||||
<%=
|
||||
render partial: 'content/contexts/relation', locals: {
|
||||
content_type: Flora,
|
||||
content: content,
|
||||
relation_class: FloraMagicalEffect,
|
||||
relation_class_id: :magic_id,
|
||||
relation_text: 'effect of'
|
||||
}
|
||||
%>
|
||||
@ -44,6 +44,6 @@
|
||||
style: 'z-index: 500;',
|
||||
method: :delete,
|
||||
data: { confirm: "Are you sure? Deleting this #{@content.class.name.downcase} cannot be undone!" } do %>
|
||||
<i class="material-icons red-text text-lighten-2">delete</i> sip
|
||||
<i class="material-icons red-text text-lighten-2">delete</i>
|
||||
<% end %>
|
||||
<% end %>
|
||||
|
||||
@ -2,7 +2,7 @@
|
||||
<div class="content-field">
|
||||
<div class="hoverable" style="padding: 8px; margin-bottom: 1rem;">
|
||||
<div>
|
||||
<%= f.label attribute, I18n.translate(
|
||||
<%= f.label attribute, I18n.translate(
|
||||
"attributes.#{f.object.class.name.downcase}.#{attribute}",
|
||||
scope: :activerecord,
|
||||
default: attribute.humanize.capitalize
|
||||
|
||||
@ -125,6 +125,8 @@
|
||||
<%= render partial: 'content/contexts/creature', locals: { content: @content } %>
|
||||
<% elsif @content.is_a? Race %>
|
||||
<%= render partial: 'content/contexts/race', locals: { content: @content } %>
|
||||
<% elsif @content.is_a? Magic %>
|
||||
<%= render partial: 'content/contexts/magic', locals: { content: @content } %>
|
||||
<% elsif @content.is_a? Language %>
|
||||
<%= render partial: 'content/contexts/language', locals: { content: @content } %>
|
||||
<% end %>
|
||||
|
||||
@ -27,7 +27,7 @@
|
||||
<a href="/about/privacy" class="white-text">Privacy Policy</a> /
|
||||
<a href="https://github.com/indentlabs/notebook" class="white-text" target="_new">Source Code</a> /
|
||||
<a href="https://www.twitter.com/indentlabs" class="white-text" target="_new">Twitter</a> /
|
||||
<a href="https://www.facebook.com/IndentLabs" class="white-text" target="_new">Facebook</a>
|
||||
<a href="https://www.facebook.com/Notebookai-556092274722663/" class="white-text" target="_new">Facebook</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@ -95,7 +95,7 @@
|
||||
%>
|
||||
|
||||
<%
|
||||
[Creature, Race, Religion, Group, Magic, Language].each do |extended_content_type|
|
||||
[Creature, Race, Religion, Group, Magic, Language, Flora].each do |extended_content_type|
|
||||
%>
|
||||
<li>
|
||||
<%= link_to polymorphic_path(extended_content_type) do %>
|
||||
|
||||
@ -26,7 +26,7 @@
|
||||
%>
|
||||
|
||||
<div class="row">
|
||||
<% [:universe, :character, :location, :item, :creature, :race, :religion, :group, :magic, :language, :scene].each do |type| %>
|
||||
<% [:universe, :character, :location, :item, :creature, :race, :religion, :group, :magic, :language, :flora, :scene].each do |type| %>
|
||||
<% content_list = current_user.send(type.to_s.pluralize) %>
|
||||
<% content_list = content_list.in_universe(@universe_scope) if (@universe_scope.present? && type != :universe) %>
|
||||
<% next if !current_user.can_create?(type.to_s.capitalize.constantize) && content_list.empty? %>
|
||||
|
||||
41
app/views/universes/content_list.html.erb
Normal file
41
app/views/universes/content_list.html.erb
Normal file
@ -0,0 +1,41 @@
|
||||
<% if @content_list.any? %>
|
||||
<div class="row">
|
||||
<div class="col s12">
|
||||
<div class="card">
|
||||
<div class="card-image", style="height: 260px; overflow-y: hidden;">
|
||||
<%= image_tag "card-headers/#{@content_type.to_s.downcase.pluralize}" %>
|
||||
<span class="card-title black lighten-3">
|
||||
<i class="material-icons <%= @content_type.color %>-text"><%= @content_type.icon %></i>
|
||||
<%= @content_type.to_s.capitalize.pluralize %>
|
||||
in
|
||||
<i class="material-icons <%= Universe.color %>-text"><%= Universe.icon %></i>
|
||||
<%= link_to @universe.name, @universe, class: 'light-blue-text' %>
|
||||
</span>
|
||||
</div>
|
||||
<div class="card-content">
|
||||
<%= render partial: 'content/list/list', locals: { content_list: @content_list } %>
|
||||
</div>
|
||||
<div class="card-action">
|
||||
<%= link_to "Back to #{@universe.name}", @universe %>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<% else %>
|
||||
<div class="center" style="margin: 50px 0">
|
||||
<h4>
|
||||
<i class="material-icons <%= Universe.color %>-text"><%= Universe.icon %></i>
|
||||
<%= link_to @universe.name, @universe %>
|
||||
doesn't contain any
|
||||
<%= @content_type.name.downcase.pluralize %> yet!
|
||||
</h4>
|
||||
<h1>
|
||||
<i class="material-icons <%= @content_type.color %>-text" style="font-size: 200%">
|
||||
<%= @content_type.icon %>
|
||||
</i>
|
||||
</h1>
|
||||
<p>
|
||||
<%= t("content_descriptions.#{@content_type.name.downcase}") %>
|
||||
</p>
|
||||
</div>
|
||||
<% end %>
|
||||
@ -75,15 +75,15 @@
|
||||
- :name: occupation
|
||||
:label: Occupation
|
||||
- :name: fave_color
|
||||
:label: Color
|
||||
:label: Favorite Color
|
||||
- :name: fave_food
|
||||
:label: Food
|
||||
:label: Favorite Food
|
||||
- :name: fave_possession
|
||||
:label: Possession
|
||||
:label: Favorite Possession
|
||||
- :name: fave_weapon
|
||||
:label: Weapon
|
||||
:label: Favorite Weapon
|
||||
- :name: fave_animal
|
||||
:label: Animal
|
||||
:label: Favorite Animal
|
||||
:history:
|
||||
:label: history
|
||||
:icon: info
|
||||
|
||||
79
config/attributes/flora.yml
Normal file
79
config/attributes/flora.yml
Normal file
@ -0,0 +1,79 @@
|
||||
:overview:
|
||||
:label: Overview
|
||||
:icon: info
|
||||
:attributes:
|
||||
- :name: name
|
||||
:label: Name
|
||||
- :name: description
|
||||
:label: Description
|
||||
- :name: aliases
|
||||
:label: Other names
|
||||
- :name: universe_id
|
||||
:label: Universe
|
||||
:classification:
|
||||
:label: Classification
|
||||
:icon: bubble_chart
|
||||
:attributes:
|
||||
- :name: order
|
||||
:label: Order
|
||||
- :name: family
|
||||
:label: Family
|
||||
- :name: genus
|
||||
:label: Genus
|
||||
- :name: related_floras
|
||||
:label: Related flora
|
||||
:appearance:
|
||||
:label: Appearance
|
||||
:icon: local_florist
|
||||
:attributes:
|
||||
- :name: colorings
|
||||
:label: Colorings
|
||||
- :name: size
|
||||
:label: Size
|
||||
- :name: smell
|
||||
:label: Smell
|
||||
- :name: taste
|
||||
:label: Taste
|
||||
:produce:
|
||||
:label: Produce
|
||||
:icon: add_box
|
||||
:attributes:
|
||||
- :name: fruits
|
||||
:label: Fruits
|
||||
- :name: seeds
|
||||
:label: Seeds
|
||||
- :name: nuts
|
||||
:label: Nuts
|
||||
- :name: berries
|
||||
:label: Berries
|
||||
- :name: medicinal_purposes
|
||||
:label: Medicinal purposes
|
||||
- :name: magics
|
||||
:label: Magical effects
|
||||
:ecosystem:
|
||||
:label: ecosystem
|
||||
:icon: language
|
||||
:attributes:
|
||||
- :name: locations
|
||||
:label: Locations
|
||||
- :name: reproduction
|
||||
:label: Reproduction
|
||||
- :name: seasonality
|
||||
:label: Seasonality
|
||||
- :name: creatures
|
||||
:label: Eaten by
|
||||
:gallery:
|
||||
:label: Gallery
|
||||
:icon: photo_library
|
||||
:changelog:
|
||||
:label: Changelog
|
||||
:icon: history
|
||||
:notes:
|
||||
:label: Notes
|
||||
:icon: edit
|
||||
:attributes:
|
||||
- :name: notes
|
||||
:label: Notes
|
||||
- :name: private_notes
|
||||
:label: Private Notes
|
||||
:description: Private notes are <em>always</em> visible to only you, even if content is made public and shared.
|
||||
@ -155,22 +155,28 @@ en:
|
||||
haircolor: Hair color
|
||||
identmarks: Identifying marks
|
||||
|
||||
location:
|
||||
map: Map
|
||||
|
||||
creature:
|
||||
name: Name
|
||||
description: Description
|
||||
type_of: Type of creature
|
||||
other_names: Other names
|
||||
|
||||
religion:
|
||||
practicing_locations: Locations
|
||||
|
||||
flora:
|
||||
magics: Magical effects
|
||||
creatures: Eaten by
|
||||
locations: Locations found
|
||||
|
||||
scene:
|
||||
scene_characters: Characters in scene
|
||||
scene_locations: Locations in scene
|
||||
scene_items: Items in scene
|
||||
|
||||
religion:
|
||||
practicing_locations: Locations
|
||||
|
||||
location:
|
||||
map: Map
|
||||
serendipitous_questions:
|
||||
attributes:
|
||||
universe:
|
||||
@ -366,6 +372,25 @@ en:
|
||||
#numbers:
|
||||
#quantifiers:
|
||||
|
||||
flora:
|
||||
name: What's the name of this flora?
|
||||
description: How would you describe %{name}?
|
||||
aliases: What other names is %{name} known by?
|
||||
|
||||
colorings: What kinds of colorings are found on %{name}?
|
||||
size: How big does %{name} grow?
|
||||
smell: What does %{name} smell like?
|
||||
taste: What does %{name} taste like?
|
||||
|
||||
fruits: What fruits does %{name} produce?
|
||||
seeds: What kinds of seeds does %{name} produce?
|
||||
nuts: What kinds of nuts does %{name} produce?
|
||||
berries: What kinds of berries does %{name} produce?
|
||||
medicinal_purposes: Does %{name} have any medicinal use?
|
||||
|
||||
reproduction: How does %{name} reproduce and spread?
|
||||
seasonality: What seasons or climates is %{name} most often found in?
|
||||
|
||||
|
||||
blacklist:
|
||||
_:
|
||||
@ -389,6 +414,7 @@ en:
|
||||
group: From fellowships to organizations
|
||||
magic: Spells, potions, and other magical things
|
||||
language: Design your own languages
|
||||
flora: The plants and nature of your world
|
||||
scene: Create scenes to organize a plot
|
||||
|
||||
content_descriptions:
|
||||
@ -417,6 +443,8 @@ en:
|
||||
Often a source of magic creates a multitude of spells, potions, and occasional trinkets.
|
||||
language: >
|
||||
Language is the bond that weaves a culture's words together. Are there any new languages in your world?
|
||||
flora: >
|
||||
The plants, flowers, trees, and other nature in your world. Paint your landscape with rich flora.
|
||||
scene: >
|
||||
Scenes are events that happen in your world, ranging in size from a nice breakfast to entire wars.
|
||||
attributefield: >
|
||||
|
||||
@ -75,7 +75,19 @@ Rails.application.routes.draw do
|
||||
# Planning
|
||||
scope '/plan' do
|
||||
# Core content types
|
||||
resources :universes
|
||||
resources :universes do
|
||||
get :characters, on: :member
|
||||
get :locations, on: :member
|
||||
get :items, on: :member
|
||||
get :creatures, on: :member
|
||||
get :races, on: :member
|
||||
get :religions, on: :member
|
||||
get :magics, on: :member
|
||||
get :languages, on: :member
|
||||
get :floras, on: :member
|
||||
get :scenes, on: :member
|
||||
get :groups, on: :member
|
||||
end
|
||||
resources :characters do
|
||||
get :autocomplete_character_name, on: :collection, as: :autocomplete_name
|
||||
end
|
||||
@ -90,6 +102,7 @@ Rails.application.routes.draw do
|
||||
resources :religions
|
||||
resources :magics
|
||||
resources :languages
|
||||
resources :floras
|
||||
|
||||
# Content usage
|
||||
resources :scenes
|
||||
|
||||
25
db/migrate/20170731000013_create_floras.rb
Normal file
25
db/migrate/20170731000013_create_floras.rb
Normal file
@ -0,0 +1,25 @@
|
||||
class CreateFloras < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :floras do |t|
|
||||
t.string :name
|
||||
t.string :description
|
||||
t.string :aliases
|
||||
t.string :order
|
||||
t.string :family
|
||||
t.string :genus
|
||||
t.string :colorings
|
||||
t.string :size
|
||||
t.string :smell
|
||||
t.string :taste
|
||||
t.string :fruits
|
||||
t.string :seeds
|
||||
t.string :nuts
|
||||
t.string :berries
|
||||
t.string :medicinal_purposes
|
||||
t.string :reproduction
|
||||
t.string :seasonality
|
||||
|
||||
t.timestamps null: false
|
||||
end
|
||||
end
|
||||
end
|
||||
5
db/migrate/20170731000608_add_user_to_flora.rb
Normal file
5
db/migrate/20170731000608_add_user_to_flora.rb
Normal file
@ -0,0 +1,5 @@
|
||||
class AddUserToFlora < ActiveRecord::Migration
|
||||
def change
|
||||
add_reference :floras, :user, index: true, foreign_key: true
|
||||
end
|
||||
end
|
||||
5
db/migrate/20170731001131_add_universe_to_flora.rb
Normal file
5
db/migrate/20170731001131_add_universe_to_flora.rb
Normal file
@ -0,0 +1,5 @@
|
||||
class AddUniverseToFlora < ActiveRecord::Migration
|
||||
def change
|
||||
add_reference :floras, :universe, index: true, foreign_key: true
|
||||
end
|
||||
end
|
||||
6
db/migrate/20170731001803_add_notes_to_flora.rb
Normal file
6
db/migrate/20170731001803_add_notes_to_flora.rb
Normal file
@ -0,0 +1,6 @@
|
||||
class AddNotesToFlora < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :floras, :notes, :string
|
||||
add_column :floras, :private_notes, :string
|
||||
end
|
||||
end
|
||||
10
db/migrate/20170731004406_create_flora_magical_effects.rb
Normal file
10
db/migrate/20170731004406_create_flora_magical_effects.rb
Normal file
@ -0,0 +1,10 @@
|
||||
class CreateFloraMagicalEffects < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :flora_magical_effects do |t|
|
||||
t.integer :flora_id
|
||||
t.integer :magic_id
|
||||
|
||||
t.timestamps null: false
|
||||
end
|
||||
end
|
||||
end
|
||||
10
db/migrate/20170731004450_create_flora_locations.rb
Normal file
10
db/migrate/20170731004450_create_flora_locations.rb
Normal file
@ -0,0 +1,10 @@
|
||||
class CreateFloraLocations < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :flora_locations do |t|
|
||||
t.integer :flora_id
|
||||
t.integer :location_id
|
||||
|
||||
t.timestamps null: false
|
||||
end
|
||||
end
|
||||
end
|
||||
10
db/migrate/20170731004509_create_flora_eaten_bies.rb
Normal file
10
db/migrate/20170731004509_create_flora_eaten_bies.rb
Normal file
@ -0,0 +1,10 @@
|
||||
class CreateFloraEatenBies < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :flora_eaten_bies do |t|
|
||||
t.integer :flora_id
|
||||
t.integer :creature_id
|
||||
|
||||
t.timestamps null: false
|
||||
end
|
||||
end
|
||||
end
|
||||
10
db/migrate/20170731004712_create_flora_relationships.rb
Normal file
10
db/migrate/20170731004712_create_flora_relationships.rb
Normal file
@ -0,0 +1,10 @@
|
||||
class CreateFloraRelationships < ActiveRecord::Migration
|
||||
def change
|
||||
create_table :flora_relationships do |t|
|
||||
t.integer :flora_id
|
||||
t.integer :related_flora_id
|
||||
|
||||
t.timestamps null: false
|
||||
end
|
||||
end
|
||||
end
|
||||
5
db/migrate/20170731010449_add_privacy_to_flora.rb
Normal file
5
db/migrate/20170731010449_add_privacy_to_flora.rb
Normal file
@ -0,0 +1,5 @@
|
||||
class AddPrivacyToFlora < ActiveRecord::Migration
|
||||
def change
|
||||
add_column :floras, :privacy, :string
|
||||
end
|
||||
end
|
||||
67
db/schema.rb
67
db/schema.rb
@ -11,7 +11,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 20170724114833) do
|
||||
ActiveRecord::Schema.define(version: 20170731010449) do
|
||||
|
||||
create_table "archenemyships", force: :cascade do |t|
|
||||
t.integer "user_id"
|
||||
@ -246,6 +246,64 @@ ActiveRecord::Schema.define(version: 20170724114833) do
|
||||
t.datetime "updated_at", null: false
|
||||
end
|
||||
|
||||
create_table "flora_eaten_bies", force: :cascade do |t|
|
||||
t.integer "flora_id"
|
||||
t.integer "creature_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
end
|
||||
|
||||
create_table "flora_locations", force: :cascade do |t|
|
||||
t.integer "flora_id"
|
||||
t.integer "location_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
end
|
||||
|
||||
create_table "flora_magical_effects", force: :cascade do |t|
|
||||
t.integer "flora_id"
|
||||
t.integer "magic_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
end
|
||||
|
||||
create_table "flora_relationships", force: :cascade do |t|
|
||||
t.integer "flora_id"
|
||||
t.integer "related_flora_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
end
|
||||
|
||||
create_table "floras", force: :cascade do |t|
|
||||
t.string "name"
|
||||
t.string "description"
|
||||
t.string "aliases"
|
||||
t.string "order"
|
||||
t.string "family"
|
||||
t.string "genus"
|
||||
t.string "colorings"
|
||||
t.string "size"
|
||||
t.string "smell"
|
||||
t.string "taste"
|
||||
t.string "fruits"
|
||||
t.string "seeds"
|
||||
t.string "nuts"
|
||||
t.string "berries"
|
||||
t.string "medicinal_purposes"
|
||||
t.string "reproduction"
|
||||
t.string "seasonality"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.integer "user_id"
|
||||
t.integer "universe_id"
|
||||
t.string "notes"
|
||||
t.string "private_notes"
|
||||
t.string "privacy"
|
||||
end
|
||||
|
||||
add_index "floras", ["universe_id"], name: "index_floras_on_universe_id"
|
||||
add_index "floras", ["user_id"], name: "index_floras_on_user_id"
|
||||
|
||||
create_table "friendly_id_slugs", force: :cascade do |t|
|
||||
t.string "slug", null: false
|
||||
t.integer "sluggable_id", null: false
|
||||
@ -603,6 +661,13 @@ ActiveRecord::Schema.define(version: 20170724114833) do
|
||||
t.datetime "updated_at", null: false
|
||||
end
|
||||
|
||||
create_table "related_floras", force: :cascade do |t|
|
||||
t.integer "flora_id"
|
||||
t.integer "related_flora_id"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
end
|
||||
|
||||
create_table "religions", force: :cascade do |t|
|
||||
t.string "name"
|
||||
t.string "description"
|
||||
|
||||
@ -3,6 +3,7 @@ Feature: Serendipitous cards
|
||||
Scenario: I update character info using a serendipitous card
|
||||
Given I am logged-in
|
||||
And I create a character
|
||||
When I view that character
|
||||
When I view the dashboard
|
||||
Then I should see my dashboard
|
||||
And I answer the Serendipitous question
|
||||
Then that new field should be saved
|
||||
|
||||
@ -31,6 +31,10 @@ When 'I log out' do
|
||||
visit destroy_user_session_path
|
||||
end
|
||||
|
||||
When(/^I view the dashboard/) do
|
||||
visit dashboard_path
|
||||
end
|
||||
|
||||
Then 'I should see my dashboard' do
|
||||
expect(current_path).to eq(dashboard_path)
|
||||
end
|
||||
@ -52,9 +56,9 @@ end
|
||||
|
||||
When(/^I change my (character|location|item|universe)\'s name$/) do |model|
|
||||
visit polymorphic_path(@model)
|
||||
click_on "Edit this #{model}"
|
||||
click_on 'edit'
|
||||
fill_in "#{model}_name", with: 'My changed name'
|
||||
click_on "Update"
|
||||
click_on 'save'
|
||||
@model.reload
|
||||
end
|
||||
|
||||
|
||||
7
test/controllers/floras_controller_test.rb
Normal file
7
test/controllers/floras_controller_test.rb
Normal file
@ -0,0 +1,7 @@
|
||||
require 'test_helper'
|
||||
|
||||
class FlorasControllerTest < ActionController::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
end
|
||||
9
test/fixtures/flora_eaten_bies.yml
vendored
Normal file
9
test/fixtures/flora_eaten_bies.yml
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
one:
|
||||
flora_id: 1
|
||||
creature_id: 1
|
||||
|
||||
two:
|
||||
flora_id: 1
|
||||
creature_id: 1
|
||||
9
test/fixtures/flora_locations.yml
vendored
Normal file
9
test/fixtures/flora_locations.yml
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
one:
|
||||
flora_id: 1
|
||||
location_id: 1
|
||||
|
||||
two:
|
||||
flora_id: 1
|
||||
location_id: 1
|
||||
9
test/fixtures/flora_magical_effects.yml
vendored
Normal file
9
test/fixtures/flora_magical_effects.yml
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
one:
|
||||
flora_id: 1
|
||||
magic_id: 1
|
||||
|
||||
two:
|
||||
flora_id: 1
|
||||
magic_id: 1
|
||||
9
test/fixtures/flora_relationships.yml
vendored
Normal file
9
test/fixtures/flora_relationships.yml
vendored
Normal file
@ -0,0 +1,9 @@
|
||||
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
one:
|
||||
flora_id: 1
|
||||
related_flora_id: 1
|
||||
|
||||
two:
|
||||
flora_id: 1
|
||||
related_flora_id: 1
|
||||
39
test/fixtures/floras.yml
vendored
Normal file
39
test/fixtures/floras.yml
vendored
Normal file
@ -0,0 +1,39 @@
|
||||
# Read about fixtures at http://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html
|
||||
|
||||
one:
|
||||
name: MyString
|
||||
description: MyString
|
||||
aliases: MyString
|
||||
order: MyString
|
||||
family: MyString
|
||||
genus: MyString
|
||||
colorings: MyString
|
||||
size: MyString
|
||||
smell: MyString
|
||||
taste: MyString
|
||||
fruits: MyString
|
||||
seeds: MyString
|
||||
nuts: MyString
|
||||
berries: MyString
|
||||
medicinal_purposes: MyString
|
||||
reproduction: MyString
|
||||
seasonality: MyString
|
||||
|
||||
two:
|
||||
name: MyString
|
||||
description: MyString
|
||||
aliases: MyString
|
||||
order: MyString
|
||||
family: MyString
|
||||
genus: MyString
|
||||
colorings: MyString
|
||||
size: MyString
|
||||
smell: MyString
|
||||
taste: MyString
|
||||
fruits: MyString
|
||||
seeds: MyString
|
||||
nuts: MyString
|
||||
berries: MyString
|
||||
medicinal_purposes: MyString
|
||||
reproduction: MyString
|
||||
seasonality: MyString
|
||||
7
test/models/flora_eaten_by_test.rb
Normal file
7
test/models/flora_eaten_by_test.rb
Normal file
@ -0,0 +1,7 @@
|
||||
require 'test_helper'
|
||||
|
||||
class FloraEatenByTest < ActiveSupport::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
end
|
||||
7
test/models/flora_location_test.rb
Normal file
7
test/models/flora_location_test.rb
Normal file
@ -0,0 +1,7 @@
|
||||
require 'test_helper'
|
||||
|
||||
class FloraLocationTest < ActiveSupport::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
end
|
||||
7
test/models/flora_magical_effect_test.rb
Normal file
7
test/models/flora_magical_effect_test.rb
Normal file
@ -0,0 +1,7 @@
|
||||
require 'test_helper'
|
||||
|
||||
class FloraMagicalEffectTest < ActiveSupport::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
end
|
||||
7
test/models/flora_relationship_test.rb
Normal file
7
test/models/flora_relationship_test.rb
Normal file
@ -0,0 +1,7 @@
|
||||
require 'test_helper'
|
||||
|
||||
class FloraRelationshipTest < ActiveSupport::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
end
|
||||
7
test/models/flora_test.rb
Normal file
7
test/models/flora_test.rb
Normal file
@ -0,0 +1,7 @@
|
||||
require 'test_helper'
|
||||
|
||||
class FloraTest < ActiveSupport::TestCase
|
||||
# test "the truth" do
|
||||
# assert true
|
||||
# end
|
||||
end
|
||||
Loading…
Reference in New Issue
Block a user