Add and hook up town/country/landmark

This commit is contained in:
Andrew Brown 2017-12-31 15:44:56 -06:00
parent e0e0fea6e6
commit cab9d0ca51
48 changed files with 628 additions and 64 deletions

BIN
app/assets/images/card-headers/.DS_Store vendored Normal file

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 99 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 90 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

View 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/

View 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/

View 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/

View File

@ -0,0 +1,3 @@
// Place all the styles related to the Countries controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

View File

@ -0,0 +1,3 @@
// Place all the styles related to the Landmarks controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

View File

@ -0,0 +1,3 @@
// Place all the styles related to the Towns controller here.
// They will automatically be included in application.css.
// You can use Sass (SCSS) here: http://sass-lang.com/

View File

@ -100,6 +100,7 @@ class ContentController < ApplicationController
return redirect_to :back
end
#todo: why is this commented out?
# Even if a user can create content, we want to double check that they're either on a premium account or creating content in a universe owned by someone on premium
# unless current_user.on_premium_plan?
# containing_universe = Universe.find(content_params[:universe_id].to_i)
@ -217,9 +218,13 @@ class ContentController < ApplicationController
end
end
# Override in content classes
def content_params
params
content_class = content_type_from_controller(self.class)
.name
.downcase
.to_sym
params.require(content_class).permit(content_param_list)
end
def content_deletion_redirect_url

View File

@ -0,0 +1,15 @@
class CountriesController < ContentController
private
def content_param_list
[
:universe_id, :user_id,
:name, :description, :other_names,
:population, :currency, :laws, :sports,
:area, :crops, :climate,
:founding_story, :established_year, :notable_wars,
:notes, :private_notes,
:privacy
]
end
end

View File

@ -71,6 +71,21 @@ class ExportController < ApplicationController
send_data to_csv(current_user.groups), filename: "groups-#{Date.today}.csv"
end
def towns_csv
report_to_mixpanel 'csv', 'towns'
send_data to_csv(current_user.towns), filename: "towns-#{Date.today}.csv"
end
def landmarks_csv
report_to_mixpanel 'csv', 'landmarks'
send_data to_csv(current_user.landmarks), filename: "landmarks-#{Date.today}.csv"
end
def countries_csv
report_to_mixpanel 'csv', 'countries'
send_data to_csv(current_user.countries), filename: "countries-#{Date.today}.csv"
end
def scenes_csv
report_to_mixpanel 'csv', 'scenes'
send_data to_csv(current_user.scenes), filename: "scenes-#{Date.today}.csv"

View File

@ -0,0 +1,14 @@
class LandmarksController < ContentController
private
def content_param_list
[
:universe_id, :user_id,
:name, :description, :other_names,
:size, :materials, :colors,
:creation_story, :established_year,
:notes, :private_notes,
:privacy
]
end
end

View File

@ -0,0 +1,14 @@
class TownsController < ContentController
private
def content_param_list
[
:universe_id, :user_id,
:name, :description, :other_names,
:laws, :sports, :politics,
:founding_story, :established_year,
:notes, :private_notes,
:privacy
]
end
end

View File

@ -0,0 +1,2 @@
module CountriesHelper
end

View File

@ -0,0 +1,2 @@
module LandmarksHelper
end

View File

@ -0,0 +1,2 @@
module TownsHelper
end

View File

@ -18,6 +18,9 @@ module HasContent
has_many :languages
has_many :groups
has_many :floras
has_many :towns
has_many :countries
has_many :landmarks
# Collective content types
has_many :scenes
@ -38,7 +41,10 @@ module HasContent
magics: magics,
languages: languages,
scenes: scenes,
groups: groups
groups: groups,
towns: towns,
countries: countries,
landmarks: landmarks
}
end
@ -54,7 +60,10 @@ module HasContent
magics,
languages,
scenes,
groups
groups,
towns,
countries,
landmarks
].flatten
end
@ -69,7 +78,10 @@ module HasContent
magics: magics.in_universe(universe_id),
languages: languages.in_universe(universe_id),
scenes: scenes.in_universe(universe_id),
groups: groups.in_universe(universe_id)
groups: groups.in_universe(universe_id),
towns: towns.in_universe(universe_id),
landmarks: landmarks.in_universe(universe_id),
countries: countries.in_universe(universe_id)
}
end
@ -85,51 +97,60 @@ module HasContent
magics.length,
languages.length,
scenes.length,
groups.length
].sum
end
groups.length,
towns.length,
landmarks.length,
countries.length
].sum
end
def public_content
{
characters: characters.is_public,
items: items.is_public,
locations: locations.is_public,
universes: universes.is_public,
creatures: creatures.is_public,
races: races.is_public,
religions: religions.is_public,
magics: magics.is_public,
languages: languages.is_public,
scenes: scenes.is_public,
groups: groups.is_public
}
end
def public_content
{
characters: characters.is_public,
items: items.is_public,
locations: locations.is_public,
universes: universes.is_public,
creatures: creatures.is_public,
races: races.is_public,
religions: religions.is_public,
magics: magics.is_public,
languages: languages.is_public,
scenes: scenes.is_public,
groups: groups.is_public,
towns: towns.is_public,
countries: countries.is_public,
landmarks: landmarks.is_public
}
end
def public_content_count
[
characters.is_public.length,
items.is_public.length,
locations.is_public.length,
universes.is_public.length,
creatures.is_public.length,
races.is_public.length,
religions.is_public.length,
magics.is_public.length,
languages.is_public.length,
scenes.is_public.length,
groups.is_public.length
].sum
end
def public_content_count
[
characters.is_public.length,
items.is_public.length,
locations.is_public.length,
universes.is_public.length,
creatures.is_public.length,
races.is_public.length,
religions.is_public.length,
magics.is_public.length,
languages.is_public.length,
scenes.is_public.length,
groups.is_public.length,
towns.is_public.length,
countries.is_public.length,
landmarks.is_public.length
].sum
end
def recent_content
[
characters, locations, items, universes,
creatures, races, religions, magics, languages,
scenes, groups
].flatten
.sort_by(&:updated_at)
.last(3)
.reverse
end
end
end
def recent_content
[
characters, locations, items, universes,
creatures, races, religions, magics, languages,
scenes, groups, towns, countries, landmarks
].flatten
.sort_by(&:updated_at)
.last(3)
.reverse
end
end
end

View File

@ -0,0 +1,39 @@
class Country < ActiveRecord::Base
acts_as_paranoid
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'
scope :is_public, -> { eager_load(:universe).where('countries.privacy = ? OR universes.privacy = ?', 'public', 'public') }
def self.content_name
'country'
end
def self.color
'lighten-2 text-lighten-2 brown'
end
def self.icon
'explore'
end
# def deleted_at
# nil #hack
# end
end

View File

@ -0,0 +1,39 @@
class Landmark < ActiveRecord::Base
acts_as_paranoid
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'
scope :is_public, -> { eager_load(:universe).where('landmark.privacy = ? OR universes.privacy = ?', 'public', 'public') }
def self.content_name
'landmark'
end
def self.color
'text-lighten-1 lighten-1 orange'
end
def self.icon
'location_on'
end
# def deleted_at
# nil #hack
# end
end

View File

@ -0,0 +1,39 @@
class Town < ActiveRecord::Base
acts_as_paranoid
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'
scope :is_public, -> { eager_load(:universe).where('towns.privacy = ? OR universes.privacy = ?', 'public', 'public') }
def self.content_name
'town'
end
def self.color
'text-lighten-3 lighten-3 purple'
end
def self.icon
'location_city'
end
# def deleted_at
# nil #hack
# end
end

View File

@ -34,6 +34,9 @@ class Universe < ActiveRecord::Base
has_many :magics
has_many :languages
has_many :floras
has_many :towns
has_many :countries
has_many :landmarks
has_many :scenes
has_many :groups

View File

@ -1,3 +0,0 @@
class Country < ActiveRecord::Base
belongs_to :universe
end

View File

@ -1,3 +0,0 @@
class Landmark < ActiveRecord::Base
belongs_to :universe
end

View File

@ -1,2 +0,0 @@
class Town < ActiveRecord::Base
end

View File

@ -30,9 +30,8 @@
<%= content_type_class.icon %>
</i>
<% end %>
<% if defined?(@content) && @content.is_a?(Universe) && content_type != :universe %>
<% if defined?(@content) && @content.is_a?(Universe) && content_type != :universe && content_type.to_s.downcase != '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" %>
<%= content_type.to_s.pluralize.titleize %>
<% else %>
<%= content_type.to_s.pluralize.titleize %>
<% end %>

View File

@ -39,6 +39,9 @@
<li><%= link_to "languages.csv", languages_csv_path %></li>
<li><%= link_to "groups.csv", groups_csv_path %></li>
<li><%= link_to "floras.csv", floras_csv_path %></li>
<li><%= link_to "towns.csv", towns_csv_path %></li>
<li><%= link_to "countries.csv", countries_csv_path %></li>
<li><%= link_to "landmarks.csv", landmarks_csv_path %></li>
<li><%= link_to "scenes.csv", scenes_csv_path %></li>
</ul>

View File

@ -0,0 +1,59 @@
:overview:
:label: Overview
:icon: info
:attributes:
- :name: name
:label: Name
- :name: description
:label: Description
- :name: other_names
:label: Other names
- :name: universe_id
:label: Universe
:culture:
:label: Culture
:icon: face
:attributes:
- :name: population
:label: Population
- :name: currency
:label: Currency
- :name: laws
:label: Laws
- :name: sports
:label: Sports
:geography:
:label: Geography
:icon: face
:attributes:
- :name: area
:label: Area
- :name: crops
:label: Crops
- :name: climate
:label: Climate
:history:
:label: History
:icon: fingerprint
:attributes:
- :name: founding_story
:label: Founding story
- :name: established_year
:label: Established year
- :name: notable_wars
:label: Notable wars
: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.

View File

@ -0,0 +1,45 @@
:overview:
:label: Overview
:icon: info
:attributes:
- :name: name
:label: Name
- :name: description
:label: Description
- :name: other_names
:label: Other names
- :name: universe_id
:label: Universe
:appearance:
:label: Appearance
:icon: face
:attributes:
- :name: size
:label: Size
- :name: materials
:label: Materials
- :name: colors
:label: Colors
:history:
:label: History
:icon: fingerprint
:attributes:
- :name: creation_story
:label: Creation story
- :name: established_year
:label: Established year
: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.

View File

@ -0,0 +1,45 @@
:overview:
:label: Overview
:icon: info
:attributes:
- :name: name
:label: Name
- :name: description
:label: Description
- :name: other_names
:label: Other names
- :name: universe_id
:label: Universe
:culture:
:label: Culture
:icon: face
:attributes:
- :name: laws
:label: Laws
- :name: sports
:label: Sports
- :name: politics
:label: Politics
:history:
:label: History
:icon: fingerprint
:attributes:
- :name: founding_story
:label: Founding story
- :name: established_year
:label: Established year
: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.

View File

@ -2,7 +2,7 @@ Rails.application.config.content_types = {
# The complete list of all content types
all: [
Universe, Character, Location, Item, Creature, Flora, Group, Language,
Magic, Race, Religion, Scene
Magic, Race, Religion, Scene, Town, Country, Landmark
],
# These content types are always on for all users, and cannot be toggled off
@ -12,13 +12,19 @@ Rails.application.config.content_types = {
default_on: [Character, Location, Item],
# These content types are available to be turned on
available: [Creature, Flora, Group, Language, Magic, Race, Religion, Scene],
available: [
Creature, Flora, Group, Language, Magic, Race, Religion, Scene,
Town, Country, Landmark
],
# These content types can be created by any user
free: [Universe, Character, Location, Item],
# These content types require a premium subscription to create
premium: [Creature, Flora, Group, Language, Magic, Race, Religion, Scene]
premium: [
Creature, Flora, Group, Language, Magic, Race, Religion, Scene, Town,
Country, Landmark
]
}
Rails.application.config.content_types[:all_non_universe] = Rails.application.config.content_types[:all] - [Universe]

View File

@ -151,6 +151,9 @@ en:
magic: Magic
language: Language
flora: Flora
town: Town
country: Country
landmark: Landmark
scene: Scene
@ -405,6 +408,47 @@ en:
reproduction: How does %{name} reproduce and spread?
seasonality: What seasons or climates is %{name} most often found in?
town:
name: What's the name of this town?
description: How would you describe %{name}?
other_names: What other names is %{name} known by?
laws: What are the major laws in %{name}?
sports: What sports are popular in %{name}?
politics: What are the politics like in %{name}?
founding_story: How was %{name} founded?
established_year: When was %{name} founded?
landmark:
name: What's the name of this landmark?
description: How would you describe %{name}?
other_names: What other names is %{name} known by?
size: How big is %{name}?
materials: What materials was %{name} constructed with?
colors: What color(s) is %{name}?
creation_story: How did %{name} originate?
established_year: When did %{name} originate?
country:
name: What's the name of this country?
description: How would you describe %{name}?
other_names: What other names is %{name} known by?
population: What is the population of %{name}?
currency: What currency is used in %{name}?
laws: What are the major laws in %{name}?
sports: What sports are popular in %{name}?
area: How big is %{name}?
crops: What crops does %{name} import or export?
climate: What is the climate like in %{name}?
founding_story: How was %{name} founded?
established_year: When was %{name} founded?
notable_wars: What notable wars has %{name} participated in?
blacklist:
_:
@ -430,6 +474,9 @@ en:
language: Design your own languages
flora: The plants and nature of your world
scene: Create scenes to organize a plot
town: Civilization's establishments
country: Kingdoms, countries, and regions
landmark: Statues, caves, peaks, and more
content_descriptions:
universe: >
@ -459,6 +506,12 @@ en:
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.
town: >
Towns across the country are pockets of interesting life, filled with characters and more.
country: >
Kingdoms, countries, regions, and more. Huge swathes of land are often claimed quickly.
landmark: >
From the smallest statue to the biggest mountain, landmarks are littered across the land.
scene: >
Scenes are events that happen in your world, ranging in size from a nice breakfast to entire wars.
attributefield: >

View File

@ -104,6 +104,9 @@ Rails.application.routes.draw do
get :floras, on: :member
get :scenes, on: :member
get :groups, on: :member
get :countries, on: :member
get :towns, on: :member
get :landmarks, on: :member
end
resources :characters do
get :autocomplete_character_name, on: :collection, as: :autocomplete_name
@ -120,6 +123,9 @@ Rails.application.routes.draw do
resources :magics
resources :languages
resources :floras
resources :towns
resources :countries
resources :landmarks
# Content usage
resources :scenes
@ -166,6 +172,9 @@ Rails.application.routes.draw do
get '/languages.csv', to: 'export#languages_csv', as: :languages_csv
get '/scenes.csv', to: 'export#scenes_csv', as: :scenes_csv
get '/groups.csv', to: 'export#groups_csv', as: :groups_csv
get '/groups.csv', to: 'export#towns_csv', as: :towns_csv
get '/groups.csv', to: 'export#countries_csv', as: :countries_csv
get '/groups.csv', to: 'export#landmarks_csv', as: :landmarks_csv
end
scope '/scene/:scene_id' do

View File

@ -0,0 +1,5 @@
class AddDeletedAtToCountries < ActiveRecord::Migration
def change
add_column :countries, :deleted_at, :datetime
end
end

View File

@ -0,0 +1,6 @@
class AddFieldsToTown < ActiveRecord::Migration
def change
add_reference :towns, :universe, index: true, foreign_key: true
add_column :towns, :deleted_at, :datetime
end
end

View File

@ -0,0 +1,5 @@
class AddDeletedAtToLandmark < ActiveRecord::Migration
def change
add_column :landmarks, :deleted_at, :datetime
end
end

View File

@ -0,0 +1,5 @@
class AddPrivacyToTowns < ActiveRecord::Migration
def change
add_column :towns, :privacy, :string
end
end

View File

@ -0,0 +1,5 @@
class AddPrivacyToCountries < ActiveRecord::Migration
def change
add_column :countries, :privacy, :string
end
end

View File

@ -0,0 +1,5 @@
class AddPrivacyToLandmarks < ActiveRecord::Migration
def change
add_column :landmarks, :privacy, :string
end
end

View File

@ -0,0 +1,5 @@
class AddUserToTowns < ActiveRecord::Migration
def change
add_reference :towns, :user, index: true, foreign_key: true
end
end

View File

@ -0,0 +1,5 @@
class AddUserToCountries < ActiveRecord::Migration
def change
add_reference :countries, :user, index: true, foreign_key: true
end
end

View File

@ -0,0 +1,5 @@
class AddUserToLandmarks < ActiveRecord::Migration
def change
add_reference :landmarks, :user, index: true, foreign_key: true
end
end

View File

@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.
ActiveRecord::Schema.define(version: 20171231174241) do
ActiveRecord::Schema.define(version: 20171231201900) do
create_table "archenemyships", force: :cascade do |t|
t.integer "user_id"
@ -213,9 +213,13 @@ ActiveRecord::Schema.define(version: 20171231174241) do
t.string "private_notes"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.datetime "deleted_at"
t.string "privacy"
t.integer "user_id"
end
add_index "countries", ["universe_id"], name: "index_countries_on_universe_id"
add_index "countries", ["user_id"], name: "index_countries_on_user_id"
create_table "creature_relationships", force: :cascade do |t|
t.integer "user_id"
@ -526,9 +530,13 @@ ActiveRecord::Schema.define(version: 20171231174241) do
t.string "private_notes"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.datetime "deleted_at"
t.string "privacy"
t.integer "user_id"
end
add_index "landmarks", ["universe_id"], name: "index_landmarks_on_universe_id"
add_index "landmarks", ["user_id"], name: "index_landmarks_on_user_id"
create_table "languages", force: :cascade do |t|
t.string "name"
@ -1145,8 +1153,15 @@ ActiveRecord::Schema.define(version: 20171231174241) do
t.string "private_notes"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
t.integer "universe_id"
t.datetime "deleted_at"
t.string "privacy"
t.integer "user_id"
end
add_index "towns", ["universe_id"], name: "index_towns_on_universe_id"
add_index "towns", ["user_id"], name: "index_towns_on_user_id"
create_table "universes", force: :cascade do |t|
t.string "name", null: false
t.text "description"

View File

@ -7,3 +7,46 @@ Checklist to create a new content type:
- rails g model Character name:string
- (can probably merge this with the below soon)
- probably want to just put core attributes here eventually, after de-systemizing other fields
- don't forget to add `privacy`, `notes`, `private_notes`, `user_id`, `universe_id`, `deleted_at`
- Move models from models/ to models/content_types/
- Add concerns to new models (mirror existing models)
- Probably just want to move them all to a single concern that injects the others eventually
- Define `self.color`, `self.icon`, `self.content_name`
- Generate CharactersController controller (inheriting from ContentController)
- define `content_params` and `content_param_list`
- use fields from the original list for the latter
- Add routes for the new content type
- `resources :characters` in /plan scope
- `get :characters, on: :member` in :universes resource
- csv routes under /export scope
- Add the content class to initializers/content_types.rb
- most likely to :all, :available, and :free/:premium
- Add the `has_many` associations to `Universe`
- Add the `has_many` associations to the `HasContent` concern
- Find and add images to images/card-headers/
- resize to 600x400 and optimize size to <100kb, ideally <50kb
- Add translations to en.yml
- class name translations under activerecord.models
- activerecord.attributes if you need a different label than humanized string
- add questions for each field to serendipitous_questions
- add line for each to content_oneliners
- add content_descriptions (of relatively the same size)
- Add config/attributes/town.yml
- Add hooks to ExportController
- Add links to export/index.html.erb
- Add links to `content` and `content_list` and `content_in_universe` and everything else in HasContent concern
- this totally needs refactored
- Give it a shot through the UI! :)
- fill in each field to make sure all fields are working/permitted
- make sure new/create and show/edit are working
- check privacy toggling

View File

@ -0,0 +1,7 @@
require 'test_helper'
class CountriesControllerTest < ActionController::TestCase
# test "the truth" do
# assert true
# end
end

View File

@ -0,0 +1,7 @@
require 'test_helper'
class LandmarksControllerTest < ActionController::TestCase
# test "the truth" do
# assert true
# end
end

View File

@ -0,0 +1,7 @@
require 'test_helper'
class TownsControllerTest < ActionController::TestCase
# test "the truth" do
# assert true
# end
end