diff options
author | Star Rauchenberger <fefferburbia@gmail.com> | 2023-10-21 00:25:50 -0400 |
---|---|---|
committer | Star Rauchenberger <fefferburbia@gmail.com> | 2023-10-21 00:25:50 -0400 |
commit | 96813a5e508a54257ef03be613a704f1f71af53d (patch) | |
tree | a50f5c8dc27304a3ca27366b6268a72804727e16 | |
parent | 2a7a19c93ee0e0d77e4e388d43f36a721c7ab715 (diff) | |
download | thoughts-96813a5e508a54257ef03be613a704f1f71af53d.tar.gz thoughts-96813a5e508a54257ef03be613a704f1f71af53d.tar.bz2 thoughts-96813a5e508a54257ef03be613a704f1f71af53d.zip |
Added quotes database
24 files changed, 587 insertions, 2 deletions
diff --git a/Gemfile b/Gemfile index 887f7eb..fd377fe 100644 --- a/Gemfile +++ b/Gemfile | |||
@@ -83,3 +83,4 @@ gem 'akismet' | |||
83 | gem 'active_storage_validations' | 83 | gem 'active_storage_validations' |
84 | gem "image_processing", ">= 1.2" | 84 | gem "image_processing", ">= 1.2" |
85 | gem "meta-tags" | 85 | gem "meta-tags" |
86 | gem 'rails_autolink' | ||
diff --git a/Gemfile.lock b/Gemfile.lock index 18f75fe..07908ec 100644 --- a/Gemfile.lock +++ b/Gemfile.lock | |||
@@ -264,6 +264,10 @@ GEM | |||
264 | rails-html-sanitizer (1.6.0) | 264 | rails-html-sanitizer (1.6.0) |
265 | loofah (~> 2.21) | 265 | loofah (~> 2.21) |
266 | nokogiri (~> 1.14) | 266 | nokogiri (~> 1.14) |
267 | rails_autolink (1.1.8) | ||
268 | actionview (> 3.1) | ||
269 | activesupport (> 3.1) | ||
270 | railties (> 3.1) | ||
267 | railties (7.0.8) | 271 | railties (7.0.8) |
268 | actionpack (= 7.0.8) | 272 | actionpack (= 7.0.8) |
269 | activesupport (= 7.0.8) | 273 | activesupport (= 7.0.8) |
@@ -382,6 +386,7 @@ DEPENDENCIES | |||
382 | paperclip | 386 | paperclip |
383 | pokeviewer! | 387 | pokeviewer! |
384 | rails (~> 7.0.3) | 388 | rails (~> 7.0.3) |
389 | rails_autolink | ||
385 | redcarpet | 390 | redcarpet |
386 | rouge | 391 | rouge |
387 | sassc-rails | 392 | sassc-rails |
diff --git a/app/assets/stylesheets/quotes.css.scss b/app/assets/stylesheets/quotes.css.scss new file mode 100644 index 0000000..8cf4eae --- /dev/null +++ b/app/assets/stylesheets/quotes.css.scss | |||
@@ -0,0 +1,4 @@ | |||
1 | /* | ||
2 | *= require normalize-rails | ||
3 | *= require_tree ./quotes | ||
4 | */ | ||
diff --git a/app/assets/stylesheets/quotes/layout.css.sass b/app/assets/stylesheets/quotes/layout.css.sass new file mode 100644 index 0000000..e5dbd64 --- /dev/null +++ b/app/assets/stylesheets/quotes/layout.css.sass | |||
@@ -0,0 +1,215 @@ | |||
1 | body | ||
2 | font-family: "Century Gothic", sans-serif | ||
3 | background-color: rgb(102,102,102) | ||
4 | |||
5 | #wrap | ||
6 | width: 80% | ||
7 | margin: 1em auto | ||
8 | background-color: white | ||
9 | border: 1px solid black | ||
10 | |||
11 | #banner | ||
12 | background-color: rgb(153,0,0) | ||
13 | font-size: 1.25em | ||
14 | font-width: bold | ||
15 | padding: 6px | ||
16 | #banner-title | ||
17 | float: left | ||
18 | a | ||
19 | text-decoration: none | ||
20 | color: white | ||
21 | #banner-abbr | ||
22 | color: white | ||
23 | font-style: italic | ||
24 | float: right | ||
25 | |||
26 | #oneliner | ||
27 | padding: 4px | ||
28 | font-style: italic | ||
29 | background-color: rgb(240,240,240) | ||
30 | a | ||
31 | color: black | ||
32 | cite:before | ||
33 | content: " \2013" | ||
34 | |||
35 | #top-bar | ||
36 | background-color: black | ||
37 | a | ||
38 | text-decoration: none | ||
39 | &:hover | ||
40 | color: purple | ||
41 | ul | ||
42 | float: right | ||
43 | padding: 4px | ||
44 | li | ||
45 | margin-left: 1em | ||
46 | display: inline | ||
47 | list-style-type: none | ||
48 | a | ||
49 | color: white | ||
50 | font-weight: bold | ||
51 | &.selected a | ||
52 | color: yellow | ||
53 | |||
54 | .pagination | ||
55 | &+.quote | ||
56 | border-top: 1px solid black | ||
57 | |||
58 | #quotes | ||
59 | .quote | ||
60 | margin: 0 | ||
61 | padding-bottom: 0.1em | ||
62 | background-color: #fcfcfc | ||
63 | border-bottom: 1px solid black | ||
64 | .quote-header | ||
65 | background-color: #f7f7f7 | ||
66 | border: 1px solid #f4f4f4 | ||
67 | margin: 0 | ||
68 | padding: 0.25em 0.75em | ||
69 | * | ||
70 | margin: 0 0.125em | ||
71 | a | ||
72 | text-decoration: none | ||
73 | .vote-link | ||
74 | color: #888 | ||
75 | .quote-upvote-link | ||
76 | color: #090 | ||
77 | font-weight: bold | ||
78 | .quote-downvote-link | ||
79 | color: #900 | ||
80 | font-weight: bold | ||
81 | .quote-link | ||
82 | font-weight: bold | ||
83 | datetime | ||
84 | font-size: 80% | ||
85 | .quote-edit-link | ||
86 | font-size: 0.9em | ||
87 | float: right | ||
88 | blockquote | ||
89 | font-family: Consolas, Monaco, "Courier New", monospace | ||
90 | font-size: 14px | ||
91 | margin: 0.5em 0.75em | ||
92 | padding: 0 | ||
93 | position: static | ||
94 | width: 100% | ||
95 | &:hover | ||
96 | background-color: #fffcec | ||
97 | .quote-header | ||
98 | background-color: #fec | ||
99 | border-color: #ffe9c9 | ||
100 | .quote-footer | ||
101 | color: #666 | ||
102 | border-top: 1px dashed #EEE | ||
103 | margin: 0 0.75em | ||
104 | padding: 0.25em 0 | ||
105 | * | ||
106 | font-size: 0.9em | ||
107 | .quote-tags | ||
108 | margin: 0 | ||
109 | padding: 0 | ||
110 | list-style-type: none | ||
111 | li | ||
112 | display: inline | ||
113 | a | ||
114 | color: #666 | ||
115 | &:before | ||
116 | content: "TAGS:" | ||
117 | .quote-notes + .quote-tags | ||
118 | margin-top: 0.5em | ||
119 | |||
120 | #page-body | ||
121 | p.normal | ||
122 | margin: .5em | ||
123 | ul | ||
124 | margin: .5em .5em .5em 2em | ||
125 | h2 | ||
126 | margin: .25em 0 0 .5em | ||
127 | h3 | ||
128 | padding-bottom: 0.25em | ||
129 | border-bottom: 1px dashed gray | ||
130 | margin: .25em 0 0 .5em | ||
131 | .form-field | ||
132 | margin: 0.5em | ||
133 | textarea | ||
134 | width: 100% | ||
135 | #about-left | ||
136 | float: left | ||
137 | width: 48% | ||
138 | margin-right: 1em | ||
139 | #about-right | ||
140 | float: right | ||
141 | width: 48% | ||
142 | margin-left: 1em | ||
143 | margin-bottom: 1em | ||
144 | |||
145 | #error-messages | ||
146 | margin: .5em | ||
147 | border: 1px solid black | ||
148 | background-color: #FF4040 | ||
149 | padding: .5em | ||
150 | h4 | ||
151 | font-size: 1.25em | ||
152 | |||
153 | #flash | ||
154 | margin: .5em | ||
155 | border: 1px solid black | ||
156 | background-color: #FBEC5D | ||
157 | padding: .5em | ||
158 | h4 | ||
159 | font-size: 1.25em | ||
160 | |||
161 | #tags-container | ||
162 | margin: 1em | ||
163 | list-style-type: none | ||
164 | li | ||
165 | display: inline | ||
166 | margin-left: 1em | ||
167 | .css1 | ||
168 | font-size: 1.0em | ||
169 | .css1_5 | ||
170 | font-size: 1.1em | ||
171 | .css2 | ||
172 | font-size: 1.2em | ||
173 | .css2_5 | ||
174 | font-size: 1.3em | ||
175 | .css3 | ||
176 | font-size: 1.4em | ||
177 | .css3_5 | ||
178 | font-size: 1.5em | ||
179 | .css4 | ||
180 | font-size: 1.6em | ||
181 | .css4_5 | ||
182 | font-size: 1.7em | ||
183 | .css5 | ||
184 | font-size: 1.8em | ||
185 | .css5_5 | ||
186 | font-size: 1.9em | ||
187 | .css6 | ||
188 | font-size: 2.0em | ||
189 | |||
190 | #search-form | ||
191 | margin: 0.5em | ||
192 | input.searchform | ||
193 | width: 50% | ||
194 | |||
195 | .audioplayer | ||
196 | float: right | ||
197 | |||
198 | footer | ||
199 | padding: 4px | ||
200 | color: white | ||
201 | text-align: center | ||
202 | font-size: 0.75em | ||
203 | clear: both | ||
204 | font-weight: bold | ||
205 | padding-bottom: .5em | ||
206 | background-color: rgb(153,0,0) | ||
207 | #footer-left | ||
208 | float: left | ||
209 | #footer-right | ||
210 | float: right | ||
211 | a | ||
212 | color: white | ||
213 | |||
214 | .cleardiv | ||
215 | clear: both \ No newline at end of file | ||
diff --git a/app/assets/stylesheets/quotes/pagination.css.scss b/app/assets/stylesheets/quotes/pagination.css.scss new file mode 100644 index 0000000..dad8b88 --- /dev/null +++ b/app/assets/stylesheets/quotes/pagination.css.scss | |||
@@ -0,0 +1,49 @@ | |||
1 | .pagination { | ||
2 | text-align: center; | ||
3 | padding: 0.3em; | ||
4 | cursor: default; | ||
5 | margin: 0.5em 0; | ||
6 | |||
7 | a, span, em { | ||
8 | padding: 0.2em 0.5em; | ||
9 | } | ||
10 | |||
11 | .disabled { | ||
12 | color: #aaaaaa; | ||
13 | } | ||
14 | |||
15 | .current { | ||
16 | font-style: normal; | ||
17 | font-weight: bold; | ||
18 | color: #ff0084; | ||
19 | } | ||
20 | |||
21 | a { | ||
22 | border: 1px solid #dddddd; | ||
23 | color: #0063dc; | ||
24 | text-decoration: none; | ||
25 | |||
26 | &:hover, &:focus { | ||
27 | border-color: #003366; | ||
28 | background: #0063dc; | ||
29 | color: white; | ||
30 | } | ||
31 | } | ||
32 | |||
33 | .page_info { | ||
34 | color: #aaaaaa; | ||
35 | padding-top: 0.8em; | ||
36 | } | ||
37 | |||
38 | .previous_page, .next_page { | ||
39 | border-width: 2px; | ||
40 | } | ||
41 | |||
42 | .previous_page { | ||
43 | margin-right: 1em; | ||
44 | } | ||
45 | |||
46 | .next_page { | ||
47 | margin-left: 1em; | ||
48 | } | ||
49 | } \ No newline at end of file | ||
diff --git a/app/controllers/quotes_controller.rb b/app/controllers/quotes_controller.rb new file mode 100644 index 0000000..fb5e33c --- /dev/null +++ b/app/controllers/quotes_controller.rb | |||
@@ -0,0 +1,97 @@ | |||
1 | class QuotesController < ApplicationController | ||
2 | def index | ||
3 | @quote = Quote.find(310) | ||
4 | @qnumber = Quote.published.count | ||
5 | @mnumber = Quote.pending.count | ||
6 | end | ||
7 | |||
8 | def latest | ||
9 | @quotes = Quote.published.order(id: :desc).paginate(page: params[:page], per_page: 10) | ||
10 | |||
11 | respond_to do |format| | ||
12 | format.html { render :list } | ||
13 | format.json { render :json => @quotes } | ||
14 | format.xml { render :xml => @quotes } | ||
15 | format.atom { render :atom => @quotes } | ||
16 | end | ||
17 | end | ||
18 | |||
19 | def top | ||
20 | @quotes = Quote.published.order(Arel.sql("(upvotes - downvotes) DESC")).paginate(page: params[:page], per_page: 10) | ||
21 | |||
22 | respond_to do |format| | ||
23 | format.html { render :list } | ||
24 | format.json { render :json => @quotes } | ||
25 | format.xml { render :xml => @quotes } | ||
26 | end | ||
27 | end | ||
28 | |||
29 | def tags | ||
30 | @tags = Quote.published.tag_counts_on(:tags) | ||
31 | end | ||
32 | |||
33 | def tag | ||
34 | @quotes = Quote.published.tagged_with(params[:id]).order(id: :desc).paginate(page: params[:page], per_page: 10) | ||
35 | |||
36 | respond_to do |format| | ||
37 | format.html { render :list } | ||
38 | format.json { render :json => @quotes } | ||
39 | format.xml { render :xml => @quotes } | ||
40 | end | ||
41 | end | ||
42 | |||
43 | def show | ||
44 | @quote = Quote.published.find(params[:id]) | ||
45 | |||
46 | respond_to do |format| | ||
47 | format.html | ||
48 | format.json { render :json => @quote } | ||
49 | format.xml { render :xml => @quote } | ||
50 | end | ||
51 | end | ||
52 | |||
53 | def new | ||
54 | end | ||
55 | |||
56 | def upvote | ||
57 | @quote = Quote.published.find(params[:id]) | ||
58 | |||
59 | respond_to do |format| | ||
60 | if @quote.upvote! request.remote_ip | ||
61 | format.html do | ||
62 | flash[:notice] = "You have upvoted Quote \"#{@quote.id}\"." | ||
63 | redirect_to @quote | ||
64 | end | ||
65 | format.js { render "voted" } | ||
66 | format.xml { head :ok } | ||
67 | else | ||
68 | format.html do | ||
69 | flash[:notice] = "You have already voted on Quote \"#{@quote.id}\"." | ||
70 | redirect_to @quote | ||
71 | end | ||
72 | format.xml { render :xml => { :error => "Someone from your IP address has already voted on this quote."} } | ||
73 | end | ||
74 | end | ||
75 | end | ||
76 | |||
77 | def downvote | ||
78 | @quote = Quote.published.find(params[:id]) | ||
79 | |||
80 | respond_to do |format| | ||
81 | if @quote.downvote! request.remote_ip | ||
82 | format.html do | ||
83 | flash[:notice] = "You have downvoted Quote \"#{@quote.id}\"." | ||
84 | redirect_to @quote | ||
85 | end | ||
86 | format.js { render "voted" } | ||
87 | format.xml { head :ok } | ||
88 | else | ||
89 | format.html do | ||
90 | flash[:notice] = "You have already voted on Quote \"#{@quote.id}\"." | ||
91 | redirect_to @quote | ||
92 | end | ||
93 | format.xml { render :xml => { :error => "Someone from your IP address has already voted on this quote."} } | ||
94 | end | ||
95 | end | ||
96 | end | ||
97 | end | ||
diff --git a/app/helpers/quotes_helper.rb b/app/helpers/quotes_helper.rb new file mode 100644 index 0000000..3c2acf9 --- /dev/null +++ b/app/helpers/quotes_helper.rb | |||
@@ -0,0 +1,11 @@ | |||
1 | module QuotesHelper | ||
2 | def quote_format(text) | ||
3 | text = text ? text.to_str : '' | ||
4 | text = text.dup if text.frozen? | ||
5 | text.gsub!(/\r\n?/, "\n") # \r\n and \r -> \n | ||
6 | text.gsub!(/\n/, '<br />') # 1 newline -> br | ||
7 | text = sanitize(text) | ||
8 | text = auto_link(text, :link => :urls) | ||
9 | text | ||
10 | end | ||
11 | end | ||
diff --git a/app/models/quote.rb b/app/models/quote.rb new file mode 100644 index 0000000..d037aab --- /dev/null +++ b/app/models/quote.rb | |||
@@ -0,0 +1,33 @@ | |||
1 | class Quote < ApplicationRecord | ||
2 | extend Enumerize | ||
3 | |||
4 | include Votable | ||
5 | |||
6 | acts_as_taggable | ||
7 | |||
8 | validates :content, presence: true | ||
9 | |||
10 | enumerize :state, | ||
11 | in: [:published, :pending, :hidden], | ||
12 | default: :published, | ||
13 | predicates: true | ||
14 | |||
15 | scope :published, -> { where(state: :published) } | ||
16 | scope :pending, -> { where(state: :pending) } | ||
17 | |||
18 | def published_date | ||
19 | created_at.strftime("%B %d %Y at %I:%M:%S") + created_at.strftime(" %p").downcase + created_at.strftime(" %Z") | ||
20 | end | ||
21 | |||
22 | def has_extra? | ||
23 | has_notes? or has_tags? | ||
24 | end | ||
25 | |||
26 | def has_notes? | ||
27 | !notes.empty? | ||
28 | end | ||
29 | |||
30 | def has_tags? | ||
31 | !tags.empty? | ||
32 | end | ||
33 | end | ||
diff --git a/app/views/layouts/quotes.html.haml b/app/views/layouts/quotes.html.haml new file mode 100644 index 0000000..6d89d91 --- /dev/null +++ b/app/views/layouts/quotes.html.haml | |||
@@ -0,0 +1,31 @@ | |||
1 | !!! 5 | ||
2 | %html | ||
3 | %head | ||
4 | %title The Four Island Quotes DB | ||
5 | %meta{ :charset => "utf-8" } | ||
6 | = stylesheet_link_tag "quotes" | ||
7 | = javascript_include_tag "application" | ||
8 | = csrf_meta_tag | ||
9 | = auto_discovery_link_tag :atom, latest_quotes_url(:atom) | ||
10 | %body | ||
11 | #wrap | ||
12 | %header#banner | ||
13 | %h1#banner-title= link_to "The Four Island Quotes DB", root_path | ||
14 | #banner-abbr FIQDB | ||
15 | .cleardiv | ||
16 | %nav#top-bar | ||
17 | %ul | ||
18 | %li= link_to_unless_current "Home", quotes_url | ||
19 | %li= link_to_unless_current "Latest", latest_quotes_url | ||
20 | %li= link_to_unless_current "Top", top_quotes_url | ||
21 | %li= link_to_unless_current "Tags", tags_quotes_url | ||
22 | %li= link_to_unless_current "Feed", latest_quotes_url(:atom) | ||
23 | .cleardiv | ||
24 | #page-body | ||
25 | - if flash[:notice] | ||
26 | #flash= flash[:notice] | ||
27 | = yield | ||
28 | %footer | ||
29 | #footer-left= raw "The Four Island Quotes DB is a #{link_to "Four Island", root_url} project and is © hatkirby 2008-#{Time.now.year}" | ||
30 | #footer-right #{Quote.published.count} approved quotes; #{Quote.pending.count} pending quotes | ||
31 | .cleardiv | ||
diff --git a/app/views/quotes/_quote.html.haml b/app/views/quotes/_quote.html.haml new file mode 100644 index 0000000..2a9fb37 --- /dev/null +++ b/app/views/quotes/_quote.html.haml | |||
@@ -0,0 +1,16 @@ | |||
1 | %article.quote{ :id => "quote-#{quote.id}" } | ||
2 | %header.quote-header{ :id => "quote-header-#{quote.id}" } | ||
3 | = link_to_unless (quote.new_record? or current_page?(quote)), "\##{quote.id}", quote, :class => "quote-link" | ||
4 | %span.vote-link{ :id => "quote-upvote-link-#{quote.id}" }= link_to_unless (quote.new_record? or quote.already_upvoted?(request.remote_ip)), "Up", upvote_quote_path(quote.id), :remote => true, :rel => "nofollow", :class => "quote-upvote-link", method: :post | ||
5 | %span.quote-rating{ :id => "quote-rating-#{quote.id}" }= "+#{quote.upvotes}/-#{quote.downvotes}" | ||
6 | %span.vote-link{ :id => "quote-downvote-link-#{quote.id}" }= link_to_unless (quote.new_record? or quote.already_downvoted?(request.remote_ip)), "Down", downvote_quote_path(quote.id), :remote => true, :rel => "nofollow", :class => "quote-downvote-link", method: :post | ||
7 | %datetime= quote.published_date | ||
8 | %blockquote.quote-body= raw quote_format(h(quote.content)) | ||
9 | - if !quote.new_record? and quote.has_extra? | ||
10 | .quote-footer | ||
11 | - if quote.has_notes? | ||
12 | .quote-notes= auto_link(quote.notes, :link => :urls) | ||
13 | - if quote.has_tags? | ||
14 | %ul.quote-tags | ||
15 | - quote.tags.each do |tag| | ||
16 | %li= link_to tag.name, tag_quotes_path(tag.name) | ||
diff --git a/app/views/quotes/index.atom.builder b/app/views/quotes/index.atom.builder new file mode 100644 index 0000000..66849cc --- /dev/null +++ b/app/views/quotes/index.atom.builder | |||
@@ -0,0 +1,11 @@ | |||
1 | atom_feed do |feed| | ||
2 | feed.title("The Four Island Quotes DB") | ||
3 | feed.updated(@quotes.first.created_at) | ||
4 | |||
5 | @quotes.each do |quote| | ||
6 | feed.entry(quote) do |entry| | ||
7 | entry.title("##{quote.id}") | ||
8 | entry.content(quote.content, :type => 'text') | ||
9 | end | ||
10 | end | ||
11 | end | ||
diff --git a/app/views/quotes/index.html.haml b/app/views/quotes/index.html.haml new file mode 100644 index 0000000..d2f667e --- /dev/null +++ b/app/views/quotes/index.html.haml | |||
@@ -0,0 +1,8 @@ | |||
1 | #about-left | ||
2 | #quotes= render @quote | ||
3 | %p.normal Welcome to the Four Island Quotes Database! Here you can find many strange and hopefully humorous Four Island quotes. There are currently #{@qnumber} quotes in the database, and there are #{@mnumber} quotes awaiting moderation. | ||
4 | #about-right | ||
5 | %h3 About | ||
6 | %p.normal The Four Island Quotes DB is a repository for humorous and memorable quotes from #{link_to "FourNet", "http://irc.fourisland.com/"} channels, instant messaging sessions, real life situations, and more. | ||
7 | %p.normal The quotes database, in its first incarnation, was created on #{link_to "April 25th 2008", "http://www.fourisland.com/2008/04/quote-time/"} by hatkirby, who was inspired by #{link_to "bash.org", "http://bash.org/"} and his obsession with record-keeping to create a quotes database for Four Island. It ran on the now-defunct PHP quote management system, #{link_to "rash", "http://rqms.sourceforge.net/"}, on the subdomain "<code>quotes.fourisland.com</code>". It was rewritten by hand and integrated into Four Island (at the URL "<code>fourisland.com/quotes</code>") by hatkirby on #{link_to "June 13th 2008", "http://www.fourisland.com/2008/06/the-new-four-island/"} with the release of Four Island 2, dubbed The New Four Island. With the release of Four Island 3 on #{link_to "September 22nd, 2011", "http://www.fourisland.com/2011/09/four-island-3/"}, it was rewritten in Ruby on Rails, disassociated from Four Island and returned to its original URL. | ||
8 | .cleardiv | ||
diff --git a/app/views/quotes/list.html.haml b/app/views/quotes/list.html.haml new file mode 100644 index 0000000..12c95c0 --- /dev/null +++ b/app/views/quotes/list.html.haml | |||
@@ -0,0 +1,4 @@ | |||
1 | %section#quotes | ||
2 | .pagination= will_paginate @quotes | ||
3 | = render @quotes | ||
4 | .pagination= will_paginate @quotes | ||
diff --git a/app/views/quotes/new.html.erb b/app/views/quotes/new.html.erb new file mode 100644 index 0000000..a4c6a0a --- /dev/null +++ b/app/views/quotes/new.html.erb | |||
@@ -0,0 +1,2 @@ | |||
1 | <h1>Quotes#new</h1> | ||
2 | <p>Find me in app/views/quotes/new.html.erb</p> | ||
diff --git a/app/views/quotes/show.html.haml b/app/views/quotes/show.html.haml new file mode 100644 index 0000000..b28c879 --- /dev/null +++ b/app/views/quotes/show.html.haml | |||
@@ -0,0 +1 @@ | |||
%section#quotes= render @quote | |||
diff --git a/app/views/quotes/tags.html.haml b/app/views/quotes/tags.html.haml new file mode 100644 index 0000000..e15b386 --- /dev/null +++ b/app/views/quotes/tags.html.haml | |||
@@ -0,0 +1,4 @@ | |||
1 | %h2 Tag Cloud | ||
2 | %ul#tags-container | ||
3 | - tag_cloud(@tags, %w(css1 css1_5 css2 css2_5 css3 css3_5 css4 css4_5 css5 css5_5 css6)) do |tag, css_class| | ||
4 | %li= link_to tag.name, tag_quotes_path(tag.name), :class => css_class | ||
diff --git a/app/views/quotes/voted.js.erb b/app/views/quotes/voted.js.erb new file mode 100644 index 0000000..c697c7d --- /dev/null +++ b/app/views/quotes/voted.js.erb | |||
@@ -0,0 +1,12 @@ | |||
1 | $("#quote-rating-<%= @quote.id %>").html('<%= escape_javascript("+#{@quote.upvotes}/-#{@quote.downvotes}") %>'); | ||
2 | |||
3 | <% if @quote.already_upvoted? request.remote_ip %> | ||
4 | $("#quote-upvote-link-<%= @quote.id %>").html("Up"); | ||
5 | <% elsif @quote.already_downvoted? request.remote_ip %> | ||
6 | $("#quote-downvote-link-<%= @quote.id %>").html("Down"); | ||
7 | <% else %> | ||
8 | $("#quote-upvote-link-<%= @quote.id %>").html('<%= escape_javascript(link_to("Up", upvote_quote_path(@quote.id), :remote => true, :rel => "nofollow", :class => "quote-upvote-link", method: :post)) %>'); | ||
9 | $("#quote-downvote-link-<%= @quote.id %>").html('<%= escape_javascript(link_to("Down", downvote_quote_path(@quote.id), :remote => true, :rel => "nofollow", :class => "quote-downvote-link", method: :post)) %>'); | ||
10 | <% end %> | ||
11 | |||
12 | $("#quote-header-<%= @quote.id %>").effect('highlight', {}, 2000); | ||
diff --git a/config/initializers/assets.rb b/config/initializers/assets.rb index e80f11f..ac7deec 100644 --- a/config/initializers/assets.rb +++ b/config/initializers/assets.rb | |||
@@ -12,4 +12,4 @@ Rails.application.config.assets.paths << Rails.root.join('node_modules') | |||
12 | # application.js, application.css, and all non-JS/CSS in the app/assets | 12 | # application.js, application.css, and all non-JS/CSS in the app/assets |
13 | # folder are already added. | 13 | # folder are already added. |
14 | # Rails.application.config.assets.precompile += %w( admin.js admin.css ) | 14 | # Rails.application.config.assets.precompile += %w( admin.js admin.css ) |
15 | Rails.application.config.assets.precompile += %w( main userdata admin ) | 15 | Rails.application.config.assets.precompile += %w( main userdata admin quotes ) |
diff --git a/config/routes.rb b/config/routes.rb index 6363590..33cc5f3 100644 --- a/config/routes.rb +++ b/config/routes.rb | |||
@@ -55,6 +55,20 @@ Rails.application.routes.draw do | |||
55 | end | 55 | end |
56 | end | 56 | end |
57 | 57 | ||
58 | resources :quotes do | ||
59 | collection do | ||
60 | get 'latest' | ||
61 | get 'top' | ||
62 | get 'tags' | ||
63 | get 'tags/:id', :action => "tag", :as => "tag" | ||
64 | end | ||
65 | |||
66 | member do | ||
67 | post 'upvote' | ||
68 | post 'downvote' | ||
69 | end | ||
70 | end | ||
71 | |||
58 | mount Pokeviewer::Engine => '/poke3' | 72 | mount Pokeviewer::Engine => '/poke3' |
59 | mount Lingo::Engine => '/lingo' | 73 | mount Lingo::Engine => '/lingo' |
60 | end | 74 | end |
diff --git a/db/migrate/20231021020306_create_quotes.rb b/db/migrate/20231021020306_create_quotes.rb new file mode 100644 index 0000000..60424e5 --- /dev/null +++ b/db/migrate/20231021020306_create_quotes.rb | |||
@@ -0,0 +1,14 @@ | |||
1 | class CreateQuotes < ActiveRecord::Migration[7.0] | ||
2 | def change | ||
3 | create_table :quotes do |t| | ||
4 | t.text :content, null: false | ||
5 | t.string :state, null: false | ||
6 | t.string :submitter | ||
7 | t.text :notes, null: false | ||
8 | t.integer :upvotes, null: false, default: 0 | ||
9 | t.integer :downvotes, null: false, default: 0 | ||
10 | |||
11 | t.timestamps | ||
12 | end | ||
13 | end | ||
14 | end | ||
diff --git a/db/schema.rb b/db/schema.rb index f8a8c49..541f1c1 100644 --- a/db/schema.rb +++ b/db/schema.rb | |||
@@ -10,7 +10,7 @@ | |||
10 | # | 10 | # |
11 | # It's strongly recommended that you check this file into your version control system. | 11 | # It's strongly recommended that you check this file into your version control system. |
12 | 12 | ||
13 | ActiveRecord::Schema[7.0].define(version: 2023_10_20_195330) do | 13 | ActiveRecord::Schema[7.0].define(version: 2023_10_21_020306) do |
14 | create_table "active_storage_attachments", force: :cascade do |t| | 14 | create_table "active_storage_attachments", force: :cascade do |t| |
15 | t.string "name", null: false | 15 | t.string "name", null: false |
16 | t.string "record_type", null: false | 16 | t.string "record_type", null: false |
@@ -324,6 +324,17 @@ ActiveRecord::Schema[7.0].define(version: 2023_10_20_195330) do | |||
324 | t.index ["world_ribbon_id"], name: "index_pokeviewer_trainers_on_world_ribbon_id" | 324 | t.index ["world_ribbon_id"], name: "index_pokeviewer_trainers_on_world_ribbon_id" |
325 | end | 325 | end |
326 | 326 | ||
327 | create_table "quotes", force: :cascade do |t| | ||
328 | t.text "content", null: false | ||
329 | t.string "state", null: false | ||
330 | t.string "submitter" | ||
331 | t.text "notes", null: false | ||
332 | t.integer "upvotes", default: 0, null: false | ||
333 | t.integer "downvotes", default: 0, null: false | ||
334 | t.datetime "created_at", null: false | ||
335 | t.datetime "updated_at", null: false | ||
336 | end | ||
337 | |||
327 | create_table "records", force: :cascade do |t| | 338 | create_table "records", force: :cascade do |t| |
328 | t.text "description" | 339 | t.text "description" |
329 | t.string "recordable_type", limit: 191 | 340 | t.string "recordable_type", limit: 191 |
diff --git a/test/controllers/quotes_controller_test.rb b/test/controllers/quotes_controller_test.rb new file mode 100644 index 0000000..a085d40 --- /dev/null +++ b/test/controllers/quotes_controller_test.rb | |||
@@ -0,0 +1,18 @@ | |||
1 | require "test_helper" | ||
2 | |||
3 | class QuotesControllerTest < ActionDispatch::IntegrationTest | ||
4 | test "should get index" do | ||
5 | get quotes_index_url | ||
6 | assert_response :success | ||
7 | end | ||
8 | |||
9 | test "should get show" do | ||
10 | get quotes_show_url | ||
11 | assert_response :success | ||
12 | end | ||
13 | |||
14 | test "should get new" do | ||
15 | get quotes_new_url | ||
16 | assert_response :success | ||
17 | end | ||
18 | end | ||
diff --git a/test/fixtures/quotes.yml b/test/fixtures/quotes.yml new file mode 100644 index 0000000..761703f --- /dev/null +++ b/test/fixtures/quotes.yml | |||
@@ -0,0 +1,17 @@ | |||
1 | # Read about fixtures at https://api.rubyonrails.org/classes/ActiveRecord/FixtureSet.html | ||
2 | |||
3 | one: | ||
4 | content: MyText | ||
5 | state: MyString | ||
6 | submitter: MyString | ||
7 | notes: MyText | ||
8 | upvotes: 1 | ||
9 | downvotes: 1 | ||
10 | |||
11 | two: | ||
12 | content: MyText | ||
13 | state: MyString | ||
14 | submitter: MyString | ||
15 | notes: MyText | ||
16 | upvotes: 1 | ||
17 | downvotes: 1 | ||
diff --git a/test/models/quote_test.rb b/test/models/quote_test.rb new file mode 100644 index 0000000..d58ff5c --- /dev/null +++ b/test/models/quote_test.rb | |||
@@ -0,0 +1,7 @@ | |||
1 | require "test_helper" | ||
2 | |||
3 | class QuoteTest < ActiveSupport::TestCase | ||
4 | # test "the truth" do | ||
5 | # assert true | ||
6 | # end | ||
7 | end | ||