Compare commits

..

1 commit

Author SHA1 Message Date
Devin Howard
619673a2d7 browser-support.md 2017-03-26 08:15:34 -07:00
335 changed files with 2089 additions and 3754 deletions

4
.github/ISSUE_TEMPLATE.md vendored Normal file
View file

@ -0,0 +1,4 @@
============
100BD/C = (100)(__)(__)/(__)=__

1
.gitignore vendored
View file

@ -15,7 +15,6 @@ app/assets/javascripts/webpacked
#secrets and config #secrets and config
.env .env
*.swp
# Ignore bundler config # Ignore bundler config
.bundle .bundle

View file

@ -12,7 +12,7 @@ Rails:
Enabled: true Enabled: true
Metrics/LineLength: Metrics/LineLength:
Max: 120 Max: 100
Metrics/AbcSize: Metrics/AbcSize:
Max: 16 Max: 16
@ -22,8 +22,3 @@ Style/Documentation:
Style/EmptyMethod: Style/EmptyMethod:
EnforcedStyle: expanded EnforcedStyle: expanded
# I like this cop, but occasionally code is more readable without a guard clause,
# and I don't want to write rubocop:disable comments every time that happens
Style/GuardClause:
Enabled: false

13
Gemfile
View file

@ -1,12 +1,11 @@
# frozen_string_literal: true # frozen_string_literal: true
source 'https://rubygems.org' source 'https://rubygems.org'
ruby '2.3.0' ruby '2.3.0'
gem 'rails', '~> 5.0.0' gem 'rails', '~> 5.0.0'
gem 'active_model_serializers' gem 'active_model_serializers'
gem 'aws-sdk', '~> 2.7.0' gem 'aws-sdk'
gem 'best_in_place' gem 'best_in_place'
gem 'delayed_job' gem 'delayed_job'
gem 'delayed_job_active_record' gem 'delayed_job_active_record'
@ -25,7 +24,7 @@ gem 'pundit'
gem 'pundit_extra' gem 'pundit_extra'
gem 'rack-attack' gem 'rack-attack'
gem 'rack-cors' gem 'rack-cors'
gem 'redis', '~> 3.3.3' gem 'redis'
gem 'slack-notifier' gem 'slack-notifier'
gem 'snorlax' gem 'snorlax'
gem 'sucker_punch' gem 'sucker_punch'
@ -38,7 +37,7 @@ gem 'uglifier'
group :test do group :test do
gem 'brakeman', require: false gem 'brakeman', require: false
gem 'factory_bot_rails' gem 'factory_girl_rails'
gem 'json-schema' gem 'json-schema'
gem 'rspec-rails' gem 'rspec-rails'
gem 'shoulda-matchers' gem 'shoulda-matchers'
@ -48,10 +47,10 @@ end
group :development, :test do group :development, :test do
gem 'better_errors' gem 'better_errors'
gem 'binding_of_caller' gem 'binding_of_caller'
gem 'faker'
gem 'pry-byebug' gem 'pry-byebug'
gem 'pry-rails' gem 'pry-rails'
gem 'rubocop', '~> 0.48.1' # match code climate https://github.com/tootsuite/mastodon/issues/1758 gem 'rubocop'
gem 'timecop'
gem 'tunemygc' gem 'tunemygc'
gem 'faker'
gem 'timecop'
end end

View file

@ -1,50 +1,50 @@
GEM GEM
remote: https://rubygems.org/ remote: https://rubygems.org/
specs: specs:
actioncable (5.0.5) actioncable (5.0.1)
actionpack (= 5.0.5) actionpack (= 5.0.1)
nio4r (>= 1.2, < 3.0) nio4r (~> 1.2)
websocket-driver (~> 0.6.1) websocket-driver (~> 0.6.1)
actionmailer (5.0.5) actionmailer (5.0.1)
actionpack (= 5.0.5) actionpack (= 5.0.1)
actionview (= 5.0.5) actionview (= 5.0.1)
activejob (= 5.0.5) activejob (= 5.0.1)
mail (~> 2.5, >= 2.5.4) mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0) rails-dom-testing (~> 2.0)
actionpack (5.0.5) actionpack (5.0.1)
actionview (= 5.0.5) actionview (= 5.0.1)
activesupport (= 5.0.5) activesupport (= 5.0.1)
rack (~> 2.0) rack (~> 2.0)
rack-test (~> 0.6.3) rack-test (~> 0.6.3)
rails-dom-testing (~> 2.0) rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2) rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (5.0.5) actionview (5.0.1)
activesupport (= 5.0.5) activesupport (= 5.0.1)
builder (~> 3.1) builder (~> 3.1)
erubis (~> 2.7.0) erubis (~> 2.7.0)
rails-dom-testing (~> 2.0) rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.3) rails-html-sanitizer (~> 1.0, >= 1.0.2)
active_model_serializers (0.10.6) active_model_serializers (0.10.4)
actionpack (>= 4.1, < 6) actionpack (>= 4.1, < 6)
activemodel (>= 4.1, < 6) activemodel (>= 4.1, < 6)
case_transform (>= 0.2) case_transform (>= 0.2)
jsonapi-renderer (>= 0.1.1.beta1, < 0.2) jsonapi (= 0.1.1.beta6)
activejob (5.0.5) activejob (5.0.1)
activesupport (= 5.0.5) activesupport (= 5.0.1)
globalid (>= 0.3.6) globalid (>= 0.3.6)
activemodel (5.0.5) activemodel (5.0.1)
activesupport (= 5.0.5) activesupport (= 5.0.1)
activerecord (5.0.5) activerecord (5.0.1)
activemodel (= 5.0.5) activemodel (= 5.0.1)
activesupport (= 5.0.5) activesupport (= 5.0.1)
arel (~> 7.0) arel (~> 7.0)
activesupport (5.0.5) activesupport (5.0.1)
concurrent-ruby (~> 1.0, >= 1.0.2) concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (~> 0.7) i18n (~> 0.7)
minitest (~> 5.1) minitest (~> 5.1)
tzinfo (~> 1.1) tzinfo (~> 1.1)
addressable (2.5.2) addressable (2.5.0)
public_suffix (>= 2.0.2, < 4.0) public_suffix (~> 2.0, >= 2.0.2)
arel (7.1.4) arel (7.1.4)
ast (2.3.0) ast (2.3.0)
aws-sdk (2.7.0) aws-sdk (2.7.0)
@ -54,82 +54,83 @@ GEM
jmespath (~> 1.0) jmespath (~> 1.0)
aws-sdk-resources (2.7.0) aws-sdk-resources (2.7.0)
aws-sdk-core (= 2.7.0) aws-sdk-core (= 2.7.0)
aws-sigv4 (1.0.2) aws-sigv4 (1.0.0)
bcrypt (3.1.11) bcrypt (3.1.11)
best_in_place (3.1.1) best_in_place (3.1.0)
actionpack (>= 3.2) actionpack (>= 3.2)
railties (>= 3.2) railties (>= 3.2)
better_errors (2.3.0) better_errors (2.1.1)
coderay (>= 1.0.0) coderay (>= 1.0.0)
erubi (>= 1.0.0) erubis (>= 2.6.6)
rack (>= 0.9.0) rack (>= 0.9.0)
binding_of_caller (0.7.2) binding_of_caller (0.7.2)
debug_inspector (>= 0.0.1) debug_inspector (>= 0.0.1)
brakeman (3.7.2) brakeman (3.4.1)
builder (3.2.3) builder (3.2.3)
byebug (9.1.0) byebug (9.0.6)
carrierwave (1.1.0) carrierwave (1.0.0)
activemodel (>= 4.0.0) activemodel (>= 4.0.0)
activesupport (>= 4.0.0) activesupport (>= 4.0.0)
mime-types (>= 1.16) mime-types (>= 1.16)
case_transform (0.2) case_transform (0.2)
activesupport activesupport
climate_control (0.2.0) climate_control (0.1.0)
cocaine (0.5.8) cocaine (0.5.8)
climate_control (>= 0.0.3, < 1.0) climate_control (>= 0.0.3, < 1.0)
coderay (1.1.2) coderay (1.1.1)
concurrent-ruby (1.0.5) concurrent-ruby (1.0.4)
debug_inspector (0.0.3) debug_inspector (0.0.2)
delayed_job (4.1.3) delayed_job (4.1.2)
activesupport (>= 3.0, < 5.2) activesupport (>= 3.0, < 5.1)
delayed_job_active_record (4.1.2) delayed_job_active_record (4.1.1)
activerecord (>= 3.0, < 5.2) activerecord (>= 3.0, < 5.1)
delayed_job (>= 3.0, < 5) delayed_job (>= 3.0, < 5)
devise (4.3.0) devise (4.2.0)
bcrypt (~> 3.0) bcrypt (~> 3.0)
orm_adapter (~> 0.1) orm_adapter (~> 0.1)
railties (>= 4.1.0, < 5.2) railties (>= 4.1.0, < 5.1)
responders responders
warden (~> 1.2.3) warden (~> 1.2.3)
diff-lcs (1.3) diff-lcs (1.3)
docile (1.1.5) docile (1.1.5)
doorkeeper (4.2.6) doorkeeper (4.2.0)
railties (>= 4.2) railties (>= 4.2)
dotenv (2.2.1) dotenv (2.1.2)
dotenv-rails (2.2.1) dotenv-rails (2.1.2)
dotenv (= 2.2.1) dotenv (= 2.1.2)
railties (>= 3.2, < 5.2) railties (>= 3.2, < 5.1)
erubi (1.6.1)
erubis (2.7.0) erubis (2.7.0)
exception_notification (4.2.2) exception_notification (4.2.1)
actionmailer (>= 4.0, < 6) actionmailer (>= 4.0, < 6)
activesupport (>= 4.0, < 6) activesupport (>= 4.0, < 6)
execjs (2.7.0) execjs (2.7.0)
factory_bot (4.8.2) factory_girl (4.8.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
factory_bot_rails (4.8.2) factory_girl_rails (4.8.0)
factory_bot (~> 4.8.2) factory_girl (~> 4.8.0)
railties (>= 3.0.0) railties (>= 3.0.0)
faker (1.8.4) faker (1.7.3)
i18n (~> 0.5) i18n (~> 0.5)
ffi (1.9.18) globalid (0.3.7)
globalid (0.4.0) activesupport (>= 4.1.0)
activesupport (>= 4.2.0) httparty (0.14.0)
httparty (0.15.6)
multi_xml (>= 0.5.2) multi_xml (>= 0.5.2)
i18n (0.9.3) i18n (0.7.0)
concurrent-ruby (~> 1.0)
jmespath (1.3.1) jmespath (1.3.1)
jquery-rails (4.3.1) jquery-rails (4.2.2)
rails-dom-testing (>= 1, < 3) rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0) railties (>= 4.2.0)
thor (>= 0.14, < 2.0) thor (>= 0.14, < 2.0)
jquery-ui-rails (6.0.1) jquery-ui-rails (6.0.1)
railties (>= 3.2.16) railties (>= 3.2.16)
json (2.1.0) json (2.0.3)
json-schema (2.8.0) json-schema (2.7.0)
addressable (>= 2.4) addressable (>= 2.4)
jsonapi-renderer (0.1.3) jsonapi (0.1.1.beta6)
jsonapi-parser (= 0.1.1.beta3)
jsonapi-renderer (= 0.1.1.beta1)
jsonapi-parser (0.1.1.beta3)
jsonapi-renderer (0.1.1.beta1)
kaminari (1.0.1) kaminari (1.0.1)
activesupport (>= 4.1.0) activesupport (>= 4.1.0)
kaminari-actionview (= 1.0.1) kaminari-actionview (= 1.0.1)
@ -144,154 +145,145 @@ GEM
kaminari-core (1.0.1) kaminari-core (1.0.1)
loofah (2.0.3) loofah (2.0.3)
nokogiri (>= 1.5.9) nokogiri (>= 1.5.9)
mail (2.6.6) mail (2.6.4)
mime-types (>= 1.16, < 4) mime-types (>= 1.16, < 4)
mailboxer (0.15.1) mailboxer (0.14.0)
carrierwave (>= 0.5.8) carrierwave (>= 0.5.8)
rails (>= 5.0.0) rails (>= 4.2.0)
method_source (0.8.2) method_source (0.8.2)
mime-types (3.1) mime-types (3.1)
mime-types-data (~> 3.2015) mime-types-data (~> 3.2015)
mime-types-data (3.2016.0521) mime-types-data (3.2016.0521)
mimemagic (0.3.2) mimemagic (0.3.2)
mini_portile2 (2.3.0) mini_portile2 (2.1.0)
minitest (5.11.1) minitest (5.10.1)
multi_xml (0.6.0) multi_xml (0.6.0)
nio4r (2.1.0) nio4r (1.2.1)
nokogiri (1.8.1) nokogiri (1.7.0.1)
mini_portile2 (~> 2.3.0) mini_portile2 (~> 2.1.0)
orm_adapter (0.5.0) orm_adapter (0.5.0)
paperclip (5.2.0) paperclip (5.1.0)
activemodel (>= 4.2.0) activemodel (>= 4.2.0)
activesupport (>= 4.2.0) activesupport (>= 4.2.0)
cocaine (~> 0.5.5) cocaine (~> 0.5.5)
mime-types mime-types
mimemagic (~> 0.3.0) mimemagic (~> 0.3.0)
parser (2.4.0.2) parser (2.3.3.1)
ast (~> 2.3) ast (~> 2.2)
pg (0.21.0) pg (0.19.0)
powerpack (0.1.1) powerpack (0.1.1)
pry (0.10.4) pry (0.10.4)
coderay (~> 1.1.0) coderay (~> 1.1.0)
method_source (~> 0.8.1) method_source (~> 0.8.1)
slop (~> 3.4) slop (~> 3.4)
pry-byebug (3.5.0) pry-byebug (3.4.2)
byebug (~> 9.1) byebug (~> 9.0)
pry (~> 0.10) pry (~> 0.10)
pry-rails (0.3.6) pry-rails (0.3.4)
pry (>= 0.10.4) pry (>= 0.9.10)
public_suffix (3.0.0) public_suffix (2.0.5)
puma (3.10.0) puma (3.6.2)
pundit (1.1.0) pundit (1.1.0)
activesupport (>= 3.0.0) activesupport (>= 3.0.0)
pundit_extra (0.3.0) pundit_extra (0.3.0)
rack (2.0.3) rack (2.0.1)
rack-attack (5.0.1) rack-attack (5.0.1)
rack rack
rack-cors (1.0.1) rack-cors (0.4.0)
rack-test (0.6.3) rack-test (0.6.3)
rack (>= 1.0) rack (>= 1.0)
rails (5.0.5) rails (5.0.1)
actioncable (= 5.0.5) actioncable (= 5.0.1)
actionmailer (= 5.0.5) actionmailer (= 5.0.1)
actionpack (= 5.0.5) actionpack (= 5.0.1)
actionview (= 5.0.5) actionview (= 5.0.1)
activejob (= 5.0.5) activejob (= 5.0.1)
activemodel (= 5.0.5) activemodel (= 5.0.1)
activerecord (= 5.0.5) activerecord (= 5.0.1)
activesupport (= 5.0.5) activesupport (= 5.0.1)
bundler (>= 1.3.0) bundler (>= 1.3.0, < 2.0)
railties (= 5.0.5) railties (= 5.0.1)
sprockets-rails (>= 2.0.0) sprockets-rails (>= 2.0.0)
rails-dom-testing (2.0.3) rails-dom-testing (2.0.2)
activesupport (>= 4.2.0) activesupport (>= 4.2.0, < 6.0)
nokogiri (>= 1.6) nokogiri (~> 1.6)
rails-html-sanitizer (1.0.3) rails-html-sanitizer (1.0.3)
loofah (~> 2.0) loofah (~> 2.0)
railties (5.0.5) railties (5.0.1)
actionpack (= 5.0.5) actionpack (= 5.0.1)
activesupport (= 5.0.5) activesupport (= 5.0.1)
method_source method_source
rake (>= 0.8.7) rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0) thor (>= 0.18.1, < 2.0)
rainbow (2.2.2) rainbow (2.2.1)
rake rake (12.0.0)
rake (12.3.0) redis (3.3.2)
rb-fsevent (0.10.2) responders (2.3.0)
rb-inotify (0.9.10) railties (>= 4.2.0, < 5.1)
ffi (>= 0.5.0, < 2) rspec-core (3.5.4)
redis (3.3.3) rspec-support (~> 3.5.0)
responders (2.4.0) rspec-expectations (3.5.0)
actionpack (>= 4.2.0, < 5.3)
railties (>= 4.2.0, < 5.3)
rspec-core (3.6.0)
rspec-support (~> 3.6.0)
rspec-expectations (3.6.0)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.6.0) rspec-support (~> 3.5.0)
rspec-mocks (3.6.0) rspec-mocks (3.5.0)
diff-lcs (>= 1.2.0, < 2.0) diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.6.0) rspec-support (~> 3.5.0)
rspec-rails (3.6.1) rspec-rails (3.5.2)
actionpack (>= 3.0) actionpack (>= 3.0)
activesupport (>= 3.0) activesupport (>= 3.0)
railties (>= 3.0) railties (>= 3.0)
rspec-core (~> 3.6.0) rspec-core (~> 3.5.0)
rspec-expectations (~> 3.6.0) rspec-expectations (~> 3.5.0)
rspec-mocks (~> 3.6.0) rspec-mocks (~> 3.5.0)
rspec-support (~> 3.6.0) rspec-support (~> 3.5.0)
rspec-support (3.6.0) rspec-support (3.5.0)
rubocop (0.48.1) rubocop (0.47.1)
parser (>= 2.3.3.1, < 3.0) parser (>= 2.3.3.1, < 3.0)
powerpack (~> 0.1) powerpack (~> 0.1)
rainbow (>= 1.99.1, < 3.0) rainbow (>= 1.99.1, < 3.0)
ruby-progressbar (~> 1.7) ruby-progressbar (~> 1.7)
unicode-display_width (~> 1.0, >= 1.0.1) unicode-display_width (~> 1.0, >= 1.0.1)
ruby-progressbar (1.9.0) ruby-progressbar (1.8.1)
sass (3.5.1) sass (3.4.23)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
sass-rails (5.0.6) sass-rails (5.0.6)
railties (>= 4.0.0, < 6) railties (>= 4.0.0, < 6)
sass (~> 3.1) sass (~> 3.1)
sprockets (>= 2.8, < 4.0) sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0) sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3) tilt (>= 1.1, < 3)
shoulda-matchers (3.1.2) shoulda-matchers (3.1.1)
activesupport (>= 4.0.0) activesupport (>= 4.0.0)
simplecov (0.15.0) simplecov (0.12.0)
docile (~> 1.1.0) docile (~> 1.1.0)
json (>= 1.8, < 3) json (>= 1.8, < 3)
simplecov-html (~> 0.10.0) simplecov-html (~> 0.10.0)
simplecov-html (0.10.2) simplecov-html (0.10.0)
slack-notifier (2.3.1) slack-notifier (2.0.0)
slop (3.6.0) slop (3.6.0)
snorlax (0.1.6) snorlax (0.1.6)
rails (> 4.1) rails (> 4.1)
sprockets (3.7.1) sprockets (3.7.1)
concurrent-ruby (~> 1.0) concurrent-ruby (~> 1.0)
rack (> 1, < 3) rack (> 1, < 3)
sprockets-rails (3.2.1) sprockets-rails (3.2.0)
actionpack (>= 4.0) actionpack (>= 4.0)
activesupport (>= 4.0) activesupport (>= 4.0)
sprockets (>= 3.0.0) sprockets (>= 3.0.0)
sucker_punch (2.0.3) sucker_punch (2.0.2)
concurrent-ruby (~> 1.0.0) concurrent-ruby (~> 1.0.0)
thor (0.20.0) thor (0.19.4)
thread_safe (0.3.6) thread_safe (0.3.5)
tilt (2.0.8) tilt (2.0.5)
timecop (0.9.1) timecop (0.8.1)
tunemygc (1.0.69) tunemygc (1.0.69)
tzinfo (1.2.4) tzinfo (1.2.2)
thread_safe (~> 0.1) thread_safe (~> 0.1)
uglifier (3.2.0) uglifier (3.0.4)
execjs (>= 0.3.0, < 3) execjs (>= 0.3.0, < 3)
unicode-display_width (1.3.0) unicode-display_width (1.1.3)
warden (1.2.7) warden (1.2.6)
rack (>= 1.0) rack (>= 1.0)
websocket-driver (0.6.5) websocket-driver (0.6.4)
websocket-extensions (>= 0.1.0) websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.2) websocket-extensions (0.1.2)
@ -300,7 +292,7 @@ PLATFORMS
DEPENDENCIES DEPENDENCIES
active_model_serializers active_model_serializers
aws-sdk (~> 2.7.0) aws-sdk
best_in_place best_in_place
better_errors better_errors
binding_of_caller binding_of_caller
@ -311,7 +303,7 @@ DEPENDENCIES
doorkeeper doorkeeper
dotenv-rails dotenv-rails
exception_notification exception_notification
factory_bot_rails factory_girl_rails
faker faker
httparty httparty
jquery-rails jquery-rails
@ -330,9 +322,9 @@ DEPENDENCIES
rack-attack rack-attack
rack-cors rack-cors
rails (~> 5.0.0) rails (~> 5.0.0)
redis (~> 3.3.3) redis
rspec-rails rspec-rails
rubocop (~> 0.48.1) rubocop
sass-rails sass-rails
shoulda-matchers shoulda-matchers
simplecov simplecov
@ -347,4 +339,4 @@ RUBY VERSION
ruby 2.3.0p0 ruby 2.3.0p0
BUNDLED WITH BUNDLED WITH
1.16.1 1.14.6

View file

@ -28,19 +28,39 @@ Metamaps is developed and maintained by a distributed, nomadic community compris
- If you would like to report a bug, please check the [issues][contributing-issues] section in our [contributing instructions][contributing]. - If you would like to report a bug, please check the [issues][contributing-issues] section in our [contributing instructions][contributing].
- If you would like to get set up as a developer, that's great! Read on for help getting your development environment set up. - If you would like to get set up as a developer, that's great! Read on for help getting your development environment set up.
## Installation for local use or development of Metamaps ## Installation
First off is getting the code downloaded to your computer. You can download a zip file from github, but if you've got `git` you can just run `git clone https://github.com/metamaps/metamaps` in your terminal. If you are on Mac or Ubuntu you can use the following instructions to quickly get a local copy of metamaps up and running using a Vagrant virtualbox. Don't be intimidated, it's easy!
```
git clone git@github.com:metamaps/metamaps.git
```
Now ensure you have VirtualBox and Vagrant installed on your computer
```
cd metamaps
./bin/configure.sh
```
This will do all the setup steps to make Metamaps work with a bit of behind the scenes ninja magick.
There are instructions for setup on various platforms, with particular support for Mac and Ubuntu, which can be found here: To start servers which will run metamaps you can then run:
- [Mac Install Walkthrough][mac-installation] ```
- [Ubuntu Install Walkthrough][ubuntu-installation] ./bin/start
```
To stop them:
```
./bin/stop
```
With your webservers running, open a web browser and go to `http://localhost:3000`
If you prefer to isolate your install in a virtual machine, you may find it simpler to setup using Vagrant: You can sign in with the default account
- [Vagrant installation][vagrant-installation] email: `user@user.com`
password: `toolsplusconsciousness`
OR create a new account at `/join`, and use access code `qwertyui`
We don't promise support for Windows, but at one point we had it running and we've kept those docs available for reference Start mapping and programming!
- [Outdated Windows Walkthrough][windows-installation]
We haven't set up instructions for using Vagrant on Windows, but there are instructions for a manual setup here:
- [For Windows][windows-installation]
## Licensing information ## Licensing information
@ -56,7 +76,4 @@ Copyright (c) 2017 Connor Turland
[license]: https://github.com/metamaps/metamaps/blob/develop/LICENSE [license]: https://github.com/metamaps/metamaps/blob/develop/LICENSE
[contributing]: https://github.com/metamaps/metamaps/blob/develop/doc/CONTRIBUTING.md [contributing]: https://github.com/metamaps/metamaps/blob/develop/doc/CONTRIBUTING.md
[contributing-issues]: https://github.com/metamaps/metamaps/blob/develop/doc/CONTRIBUTING.md#reporting-bugs-and-other-issues [contributing-issues]: https://github.com/metamaps/metamaps/blob/develop/doc/CONTRIBUTING.md#reporting-bugs-and-other-issues
[mac-installation]: https://github.com/metamaps/metamaps/blob/develop/doc/MacInstallation.md
[ubuntu-installation]: https://github.com/metamaps/metamaps/blob/develop/doc/UbuntuInstallation.md
[vagrant-installation]: https://github.com/metamaps/metamaps/blob/develop/doc/VagrantInstallation.md
[windows-installation]: https://github.com/metamaps/metamaps/blob/develop/doc/WindowsInstallation.md [windows-installation]: https://github.com/metamaps/metamaps/blob/develop/doc/WindowsInstallation.md

1
Rakefile Executable file → Normal file
View file

@ -1,6 +1,5 @@
#!/usr/bin/env rake #!/usr/bin/env rake
# frozen_string_literal: true # frozen_string_literal: true
# Add your own tasks in files placed in lib/tasks ending in .rake, # Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.

2
Vagrantfile vendored
View file

@ -37,7 +37,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
config.vm.box = 'trusty64' config.vm.box = 'trusty64'
config.vm.box_url = 'http://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box' config.vm.box_url = 'http://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box'
config.vm.network :forwarded_port, guest: 3000, host: 3000 config.vm.network :forwarded_port, guest: 3000, host: 3000
config.vm.network :forwarded_port, guest: 5000, host: 5000 config.vm.network :forwarded_port, guest: 5001, host: 5001
config.vm.network 'private_network', ip: '10.0.1.11' config.vm.network 'private_network', ip: '10.0.1.11'
config.vm.synced_folder '.', '/vagrant', nfs: true config.vm.synced_folder '.', '/vagrant', nfs: true

Binary file not shown.

After

Width:  |  Height:  |  Size: 543 B

View file

@ -4,11 +4,11 @@ $(document).ready(function() {
if (window.location.pathname === '/') { if (window.location.pathname === '/') {
$.ajax({ $.ajax({
type: 'GET', type: 'GET',
url: 'https://i.vimeocdn.com/video/', url: 'https://player.vimeo.com',
error: function(e) { error: function(e) {
$('.homeVideo').hide() $('.homeVideo').hide()
$('.homeVideo').replaceWith($('<video/>', { $('.homeVideo').replaceWith($('<video/>', {
poster: '<%= asset_path('metamaps-intro-poster.webp') %>', poster: '/assets/metamaps-intro-poster.webp',
width: '560', width: '560',
height: '315', height: '315',
class: 'homeVideo', class: 'homeVideo',

View file

@ -56,15 +56,16 @@
} }
li.toggledOff { li.toggledOff {
opacity: 0.6; opacity: 0.4;
} }
} }
.centerContent { .blackBox {
width: 760px; width: 760px;
margin: 0 auto; margin: 0 auto;
padding: 80px 0 60px 20px; padding: 80px 0 60px 20px;
background: rgba(125, 125, 125, 0.4); background: rgba(0, 0, 0, 0.4);
color: white;
overflow: hidden; overflow: hidden;
position: relative; position: relative;
@ -84,10 +85,10 @@
display: table-row; display: table-row;
} }
tr:nth-child(odd) { tr:nth-child(odd) {
background: rgba(125, 125, 125, 0.2); background: rgba(0, 0, 0, 0.2);
} }
tr:nth-child(even) { tr:nth-child(even) {
background: rgba(125, 125, 125, 0.3); background: rgba(0, 0, 0, 0.3);
} }
th, th,
td { td {

View file

@ -826,7 +826,6 @@ label {
font-size: 14px; font-size: 14px;
line-height: 14px; line-height: 14px;
color: #757575; color: #757575;
cursor: pointer;
} }
.accountListItem:hover { .accountListItem:hover {
color: #424242; color: #424242;
@ -1915,10 +1914,14 @@ input.collaboratorSearchField {
background-position: -32px 0; background-position: -32px 0;
} }
.yourMap .mapPermission:hover { .yourMap .mapPermission:hover {
background-image: url(<%= asset_data_uri('arrowperms_sprite.png') %>);
cursor: pointer; cursor: pointer;
background-position: -32px 0;
} }
.yourMap .mapPermission.minimize { .yourMap .mapPermission.minimize {
background-image: url(<%= asset_data_uri('arrowperms_sprite.png') %>) !important;
cursor: pointer; cursor: pointer;
background-position: 0 0;
} }
.mapInfoBox .mapPermission .permissionSelect { .mapInfoBox .mapPermission .permissionSelect {
list-style: none; list-style: none;
@ -2930,6 +2933,136 @@ and it won't be important on password protected instances */
color: #424242; color: #424242;
} }
/* Admin Pages */
.blackBox {
width: 760px;
margin: 0 auto;
padding: 20px 0 60px 20px;
background: rgba(0, 0, 0, 0.4);
color: white;
overflow: hidden;
position: relative;
}
.blackBox .metacodeSetsDescription {
width: 314px;
}
.blackBox td.metacodeSetDesc {
width: 314px;
word-wrap: break-word;
}
.blackBox .metacodeSetImage {
width: 36px;
height: 36px;
float: left;
}
.blackBox tr {
display: table-row;
}
.blackBox tr:nth-child(odd) {
background: rgba(0, 0, 0, 0.2);
}
.blackBox tr:nth-child(even) {
background: rgba(0, 0, 0, 0.3);
}
.blackBox th,
.blackBox td {
padding: 10px;
}
.blackBox td.iconURL {
max-width: 415px;
word-wrap: break-word;
}
.blackBox td.iconColor {
}
.blackBox .field {
margin: 15px 0 5px;
}
.blackBox label {
float: left;
width: 100px;
margin-right: 15px;
}
.blackBox input[type="text"] {
width: 336px;
height: 32px;
font-size: 15px;
direction: ltr;
-webkit-appearance: none;
appearance: none;
display: inline-block;
margin: 0;
padding: 0 8px;
background: #fff;
border: 1px solid #d9d9d9;
border-top: 1px solid #c0c0c0;
-webkit-box-sizing: border-box;
-moz-box-sizing: border-box;
box-sizing: border-box;
-webkit-border-radius: 1px;
-moz-border-radius: 1px;
border-radius: 1px;
font: -webkit-small-control;
color: initial;
letter-spacing: normal;
word-spacing: normal;
text-transform: none;
text-indent: 0px;
text-shadow: none;
display: inline-block;
text-align: start;
font-family: arial;
}
.blackBox input[type="text"]:hover,
.blackBox textarea:hover {
border: 1px solid #b9b9b9;
border-top: 1px solid #a0a0a0;
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
-moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
}
.blackBox textarea {
padding: 8px;
border: 1px solid #d9d9d9;
border-top: 1px solid #c0c0c0;
resize: none;
font: -webkit-small-control;
letter-spacing: normal;
word-spacing: normal;
text-transform: none;
text-indent: 0px;
text-shadow: none;
text-align: start;
font-family: arial;
font-size: 15px;
line-height: 17px;
width: 318px;
}
.blackBox .allMetacodes {
padding: 5px 0;
}
.blackBox a.button {
margin-right: 20px;
line-height: 40px;
}
.blackBox a.button,
.blackBox input.add {
float: left;
margin-top: 5px;
height: 40px;
font-size: 17px;
width: auto;
padding: 0 30px;
cursor: pointer;
font-weight: normal;
}
.blackBox a.button:hover,
.blackBox input.add:hover {
-webkit-box-shadow: none;
box-shadow: none;
}
/* request */ /* request */
.requestInvite { .requestInvite {
@ -3017,15 +3150,11 @@ script.data-gratipay-username {
} }
.topicFollow { .topicFollow {
height: 24px; text-align: center;
line-height: 24px; height: 48px;
line-height: 48px;
border-top: 1px solid #BDBDBD;
background: #FFF;
cursor: pointer; cursor: pointer;
font-family: helvetica, sans-serif; font-family: din-regular;
float: left;
width: 72px;
text-align: right;
padding: 12px 0;
color: #4fb5c0;
font-size: 13px;
font-weight: bold;
} }

View file

@ -1,12 +1,9 @@
$mid-gray: #8A8A8A;
$mid-gray-opacity: rgba(66, 66, 66, 0.6);
.nameCounter { .nameCounter {
position: absolute; position: absolute;
bottom: 1px; bottom: 1px;
right: 2px; right: 2px;
font-size: 11px; font-size: 11px;
font-family: helvetica, sans-serif; font-family: helvetica;
color: #727272; color: #727272;
line-height: 11px; line-height: 11px;
display: none; display: none;
@ -45,7 +42,7 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
z-index:2; z-index:2;
color: #424242; color: #424242;
border-radius:2px; border-radius:2px;
box-shadow: 2px 3px 3px rgba(125, 125, 125, 0.23), -2px -1px 3px rgba(125, 125, 125, 0.16); box-shadow: 0px 3px 3px rgba(0,0,0,0.23), 0 3px 3px rgba(0,0,0,0.16);
} }
.text { .text {
@ -67,6 +64,7 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
display:block; display:block;
position:relative; position:relative;
width:100%; width:100%;
min-height:360px;
z-index: 25; z-index: 25;
} }
.CardOnGraph.hasAttachment { .CardOnGraph.hasAttachment {
@ -75,10 +73,11 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
.CardOnGraph .title { .CardOnGraph .title {
word-break: break-word; word-break: break-word;
font-size: 20px; font-size: 18px;
line-height: 24px; line-height: 22px;
display: table; display: table;
padding: 20px 0; padding: 8px 0 16px;
height: 80px;
text-align: center; text-align: center;
font-family: 'din-regular', sans-serif; font-family: 'din-regular', sans-serif;
width: 300px; width: 300px;
@ -89,6 +88,11 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
display: table-cell; display: table-cell;
vertical-align: middle; vertical-align: middle;
padding: 0 16px; padding: 0 16px;
&.riek-editing {
position: absolute;
top: 32px;
}
} }
.canEdit #titleActivator:hover { .canEdit #titleActivator:hover {
background-image: url(<%= asset_data_uri('edit.png') %>); background-image: url(<%= asset_data_uri('edit.png') %>);
@ -100,8 +104,9 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
.showcard .title .riek-editing { .showcard .title .riek-editing {
font-family: 'din-regular', sans-serif; font-family: 'din-regular', sans-serif;
color: #424242; color: #424242;
font-size: 20px; font-size: 18px;
line-height: 24px; line-height: 22px;
height: 3em;
padding: 5px 0; padding: 5px 0;
width: 100%; width: 100%;
margin: 0; margin: 0;
@ -115,23 +120,11 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
.CardOnGraph .scroll { .CardOnGraph .scroll {
display:block; display:block;
padding: 8px 0 8px 16px; padding: 8px 0 8px 16px;
height: 152px;
font-size: 13px; font-size: 13px;
line-height:15px; line-height:15px;
font-family: helvetica, sans-serif; font-family: helvetica, sans-serif;
overflow-y: auto; overflow-y: auto;
p.emptyDesc {
color: $mid-gray-opacity;
}
a.mdSupport {
color: #4fb5c0;
font-size: 11px;
display: none;
}
.riek-editing + .mdSupport {
display: block;
}
} }
.CardOnGraph.hasAttachment .scroll { .CardOnGraph.hasAttachment .scroll {
height: auto; height: auto;
@ -143,12 +136,14 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
font-family: helvetica, sans-serif; font-family: helvetica, sans-serif;
color: #424242; color: #424242;
padding: 0; padding: 0;
width: 258px; width: 100%;
margin: 0; margin: 0;
border: 0; border: 0;
outline: none; outline: none;
font-size: 12px;
line-height: 15px;
background: none; background: none;
overflow-y: scroll; resize: none;
} }
/* /*
@ -182,9 +177,12 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
.CardOnGraph .riek_desc { .CardOnGraph .riek_desc {
display:block; display:block;
padding-right: 26px; margin-top:2px;
padding-right: 18px;
margin-right: 8px;
min-height: 7em;
} }
.canEdit .CardOnGraph .riek_desc:not(.riek-editing):hover { .canEdit .CardOnGraph .riek_desc:hover {
background-image: url(<%= asset_data_uri('edit.png') %>); background-image: url(<%= asset_data_uri('edit.png') %>);
background-position: top right; background-position: top right;
background-repeat: no-repeat; background-repeat: no-repeat;
@ -197,7 +195,9 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
.CardOnGraph .links { .CardOnGraph .links {
position: relative; position: relative;
z-index: 2; border-bottom: 1px solid #BDBDBD;
border-top: 1px solid #BDBDBD;
background-color: #e0e0e0;
.linkItem { .linkItem {
float: left; float: left;
@ -213,52 +213,37 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
} }
.icon { .icon {
position: absolute;
z-index: 1;
padding: 0; padding: 0;
height: 48px; height: 48px;
margin-right: 10px; width: 100%;
.metacodeImage { .metacodeImage {
cursor: move; cursor: move;
position: absolute; position: relative;
left: -18px; left: -23px;
top: 6px; top: 1px;
width: 36px; width: 46px;
height: 36px; height: 46px;
background-size:36px 36px; background-size:46px 46px;
background-position:0 0; background-position:0 0;
background-repeat:no-repeat; background-repeat:no-repeat;
} }
} }
}
.CardOnGraph .info {
position: relative;
.linkItem {
float: left;
z-index: 1;
position: relative;
color: $mid-gray-opacity;
font-size: 14px;
line-height: 14px;
a {
color: $mid-gray-opacity;
}
}
.contributor { .contributor {
bottom: 7px; bottom: 7px;
margin-left: 16px; margin-left: 40px;
.contributorIcon { .contributorIcon {
position: relative; position: relative;
display: inline-block;
vertical-align: middle; vertical-align: middle;
border-radius: 16px; border-radius: 16px;
margin: 5px 5px 5px 0; margin: 5px;
top: 11px; top: 8px;
left: 0; left: 0;
border-radius: 16px;
} }
span { span {
@ -267,34 +252,52 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
} }
.contributorName { .contributorName {
display: none;
position: absolute;
background: black;
text-align: center;
color: white;
border-radius: 2px;
font-family: din-regular; font-family: din-regular;
margin-top: 20px; line-height: 15px;
display: inline-block; font-size: 12px;
vertical-align: middle; padding: 3px 5px 2px;
width: 97px;
padding: 0 8px 0 4px;
white-space: nowrap; white-space: nowrap;
overflow: hidden; margin-top: 8px;
text-overflow: ellipsis;
&:before {
content: '';
position: absolute;
top: 26px;
left: 10px;
margin-top: -30px;
width: 0;
height: 0;
border-bottom: 4px solid #000000;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
}
}
&:hover .contributorName {
display: block;
} }
} }
.mapCount { .mapCount {
padding:17px 38px 17px 0; padding:17px 0 17px 36px;
width: 22px; margin-left: 12px;
text-align: right;
.mapCountIcon { .mapCountIcon {
position: absolute; position: absolute;
top: 8px; top: 8px;
right: 0; left: 0;
width: 32px; width: 32px;
height: 32px; height: 32px;
background-image: url(<%= asset_data_uri('map32_sprite.png') %>); background-image: url(<%= asset_data_uri('map32_sprite.png') %>);
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: 0 0; background-position: 0 0;
cursor: pointer; cursor: pointer;
opacity: 0.6;
} }
&:hover .mapCountIcon { &:hover .mapCountIcon {
@ -303,18 +306,18 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
.tip, .hoverTip { .tip, .hoverTip {
top: 44px; top: 44px;
right: 0px; left: 0px;
font-size: 12px !important; font-size: 12px !important;
&:before { &:before {
content: ''; content: '';
position: absolute; position: absolute;
top: 26px; top: 26px;
right: 10px; left: 10px;
margin-top: -30px; margin-top: -30px;
width: 0; width: 0;
height: 0; height: 0;
border-bottom: 4px solid $mid-gray; border-bottom: 4px solid #000000;
border-left: 5px solid transparent; border-left: 5px solid transparent;
border-right: 5px solid transparent; border-right: 5px solid transparent;
} }
@ -324,9 +327,10 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
white-space: nowrap; white-space: nowrap;
font-family: 'din-regular'; font-family: 'din-regular';
top: 44px; top: 44px;
left: 0px;
font-size: 12px !important; font-size: 12px !important;
position: absolute; position: absolute;
background: $mid-gray; background: black;
color: white; color: white;
border-radius: 4px; border-radius: 4px;
line-height: 17px; line-height: 17px;
@ -358,31 +362,28 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
} }
.synapseCount { .synapseCount {
width: 22px; margin-left: 26px;
padding:17px 38px 17px 0; width: 24px;
text-align: right; padding:17px 0 17px 32px;
margin-right: 4px;
.synapseCountIcon { .synapseCountIcon {
position: absolute; position: absolute;
top: 8px; top: 8px;
right: 0; left: 0;
width: 32px; width: 32px;
height: 32px; height: 32px;
background-image: url(<%= asset_data_uri('synapse32_sprite.png') %>); background-image: url(<%= asset_data_uri('synapse32_sprite.png') %>);
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: 0 0; background-position: 0 0;
opacity: 0.6;
} }
hover .synapseCountIcon { hover .synapseCountIcon {
background-position: 0 -32px; background-position: 0 -32px;
} }
.tip { .tip {
position: absolute; position: absolute;
background: $mid-gray; background: black;
width: auto; width: auto;
top: 44px; top: 44px;
right: 0px;
color: white; color: white;
white-space: nowrap; white-space: nowrap;
border-radius: 2px; border-radius: 2px;
@ -397,10 +398,10 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
content: ''; content: '';
position: absolute; position: absolute;
margin-top: -8px; margin-top: -8px;
right: 12px; margin-left: 6px;
width: 0; width: 0;
height: 0; height: 0;
border-bottom: 4px solid $mid-gray; border-bottom: 4px solid black;
border-left: 5px solid transparent; border-left: 5px solid transparent;
border-right: 5px solid transparent; border-right: 5px solid transparent;
} }
@ -412,10 +413,6 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
color: #4FC059; color: #4FC059;
} }
.linkItem.mapPerm {
margin-right: 8px;
}
.mapPerm { .mapPerm {
width: 32px; width: 32px;
height: 32px; height: 32px;
@ -437,10 +434,14 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
} }
.yourTopic .mapPerm:hover, .yourEdge .mapPerm:hover { .yourTopic .mapPerm:hover, .yourEdge .mapPerm:hover {
background-image: url(<%= asset_data_uri('arrowperms_sprite.png') %>);
background-position: -32px 0;
cursor:pointer; cursor:pointer;
} }
.yourTopic .mapPerm.minimize, .yourEdge .mapPerm.minimize { .yourTopic .mapPerm.minimize, .yourEdge .mapPerm.minimize {
cursor: pointer; background-image: url(<%= asset_data_uri('arrowperms_sprite.png') %>) !important;
background-position: 0 0;
cursor: pointer;
} }
.mapPerm .permissionSelect { .mapPerm .permissionSelect {
list-style: none; list-style: none;
@ -476,34 +477,32 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
} }
.CardOnGraph .metacodeTitle { .CardOnGraph .metacodeTitle {
font-family: 'din-regular'; font-style: italic;
font-family: 'vinyl';
text-transform: uppercase;
position: absolute;
line-height: 24px; line-height: 24px;
height: 26px; height: 26px;
font-size: 18px; font-size: 24px;
padding: 13px 24px 9px 24px; display: none;
width: 90%;
padding: 13px 0 9px 10%;
background-color: #E0E0E0;
color: #424242; color: #424242;
width: 120px;
max-width: 120px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
} }
.permission.canEdit .metacodeTitle { .permission.canEdit .metacodeTitle {
cursor:pointer; cursor:pointer;
} }
.permission.canEdit .expandMetacodeSelect { .permission.canEdit .expandMetacodeSelect {
position: relative; position: absolute;
top: 2px; top: 16px;
left: 4px; right: 16px;
width: 16px; width: 16px;
height: 16px; height: 16px;
background-image: url(<%= asset_data_uri('arrowright_sprite.png') %>); background-image: url(<%= asset_data_uri('arrowright_sprite.png') %>);
background-repeat: no-repeat; background-repeat: no-repeat;
background-position: 0 -32px; background-position: 0 -32px;
display: inline-block;
-webkit-transform: rotate(90deg);
transform: rotate(90deg);
} }
.permission.canEdit .minimize .expandMetacodeSelect { .permission.canEdit .minimize .expandMetacodeSelect {
@ -520,8 +519,8 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
background: #EAEAEA; background: #EAEAEA;
white-space: nowrap; white-space: nowrap;
position: absolute; position: absolute;
top: 48px; left: 300px;
box-shadow: 2px 2px 2px rgba(125, 125, 125, 0.23), -2px -1px 3px rgba(125, 125, 125, 0.16); top: -1px;
} }
.CardOnGraph .metacodeSelect ul { .CardOnGraph .metacodeSelect ul {
position: relative; position: relative;
@ -614,9 +613,9 @@ background-color: #E0E0E0;
} }
.CardOnGraph .tip { .CardOnGraph .tip {
position: absolute; position: absolute;
background: $mid-gray; background: black;
top: 35px; top: 35px;
right: 0; left: 0;
color: white; color: white;
border-radius: 4px; border-radius: 4px;
font-size:15px !important; font-size:15px !important;
@ -634,6 +633,7 @@ background-color: #E0E0E0;
width:100%; width:100%;
height:47px; height:47px;
position: relative; position: relative;
border-top: 1px solid #BDBDBD;
} }
.link-adder a { .link-adder a {
@ -695,9 +695,9 @@ background-color: #E0E0E0;
} }
#addLinkInput input{ #addLinkInput input{
padding: 9px 27px 9px 31px; padding: 9px 7px 9px 31px;
height: 12px; height: 12px;
width: 210px; width: 198px;
margin: 0 0 0 0; margin: 0 0 0 0;
border: none; border: none;
outline: none; outline: none;

View file

@ -668,19 +668,19 @@
box-shadow: 0px 3px 3px rgba(0,0,0,0.23), 0 3px 3px rgba(0,0,0,0.16); box-shadow: 0px 3px 3px rgba(0,0,0,0.23), 0 3px 3px rgba(0,0,0,0.16);
} }
#navBar { #exploreMapsHeader {
position: absolute; position: absolute;
width: 100%; width: 100%;
} }
.navBarContainer { .exploreMapsBar {
z-index:2; z-index:2;
background-color:#FAFAFA; background-color:#FAFAFA;
height: 42px; height: 42px;
padding-top: 52px; padding-top: 52px;
} }
.navBarMenu { .exploreMapsMenu {
display: block; display: block;
width: 100%; width: 100%;
height:42px; height:42px;
@ -689,29 +689,30 @@
text-align: center; text-align: center;
} }
.navBarCenter { .exploreMapsCenter {
display: block; display: block;
} }
.navBarButton { .exploreMapsButton {
color: #757575; color: #757575;
cursor: default; cursor: default;
font-weight: normal; font-weight: normal;
font-family: 'din-medium'; font-family: 'din-medium';
font-size: 14px; font-size: 14px;
padding: 0 8px; height: 14px;
border-bottom: 2px solid rgba(0,0,0,0); padding: 14px 8px 12px 40px;
border-bottom: 2px solid rgba(0,0,0,0);
display: inline-block; display: inline-block;
cursor: pointer; cursor: pointer;
position:relative; position:relative;
} }
.navBarButton:hover, .navBarButton.active { .exploreMapsButton:hover, .exploreMapsButton.active {
text-decoration: none; text-decoration: none;
color: #424242; color: #424242;
border-bottom: 2px solid #00BCD4; border-bottom: 2px solid #00BCD4;
} }
.navBarButton.mapperButton { .exploreMapsButton.mapperButton {
height: 40px; height: 40px;
padding: 0; padding: 0;
} }
@ -728,69 +729,62 @@
} }
.navBarButton .navBarIcon { .exploreMapsButton .exploreMapsIcon {
background-repeat: no-repeat; background-repeat: no-repeat;
width:32px; width:32px;
height:32px; height:32px;
margin-top:5px; position:absolute;
margin-left:5px; top:5px;
margin-right: 5px; left:5px;
display: inline-block;
vertical-align: top;
} }
.navBarLinkText { .exploreMapsCenter .authedApps .exploreMapsIcon {
padding: 11px 0 12px 0;
display: inline-block;
}
.navBarCenter .authedApps .navBarIcon {
background-image: url(<%= asset_path('user_sprite.png') %>); background-image: url(<%= asset_path('user_sprite.png') %>);
background-position: 0 -32px; background-position: 0 -32px;
} }
.navBarCenter .myMaps .navBarIcon { .exploreMapsCenter .myMaps .exploreMapsIcon {
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>); background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
background-position: -32px 0; background-position: -32px 0;
} }
.navBarCenter .sharedMaps .navBarIcon { .exploreMapsCenter .sharedMaps .exploreMapsIcon {
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>); background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
background-position: -128px 0; background-position: -128px 0;
} }
.navBarCenter .activeMaps .navBarIcon { .exploreMapsCenter .activeMaps .exploreMapsIcon {
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>); background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
background-position: 0 0; background-position: 0 0;
} }
.navBarCenter .featuredMaps .navBarIcon { .exploreMapsCenter .featuredMaps .exploreMapsIcon {
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>); background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
background-position: -96px 0; background-position: -96px 0;
} }
.navBarCenter .starredMaps .navBarIcon { .exploreMapsCenter .starredMaps .exploreMapsIcon {
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>); background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
background-position: -96px 0; background-position: -96px 0;
} }
.navBarCenter .notificationsLink .navBarIcon { .exploreMapsCenter .notificationsLink .exploreMapsIcon {
background-image: url(<%= asset_path 'topright_sprite.png' %>); background-image: url(<%= asset_path 'topright_sprite.png' %>);
background-position: -128px 0; background-position: -128px 0;
} }
.authedApps:hover .navBarIcon, .authedApps.active .navBarIcon { .authedApps:hover .exploreMapsIcon, .authedApps.active .exploreMapsIcon {
background-position-x: -32px; background-position-x: -32px;
} }
.myMaps:hover .navBarIcon, .myMaps.active .navBarIcon { .myMaps:hover .exploreMapsIcon, .myMaps.active .exploreMapsIcon {
background-position: -32px -32px; background-position: -32px -32px;
} }
.activeMaps:hover .navBarIcon, .activeMaps.active .navBarIcon { .activeMaps:hover .exploreMapsIcon, .activeMaps.active .exploreMapsIcon {
background-position: 0 -32px; background-position: 0 -32px;
} }
.featuredMaps:hover .navBarIcon, .featuredMaps.active .navBarIcon { .featuredMaps:hover .exploreMapsIcon, .featuredMaps.active .exploreMapsIcon {
background-position: -96px -32px; background-position: -96px -32px;
} }
.starredMaps:hover .navBarIcon, .starredMaps.active .navBarIcon { .starredMaps:hover .exploreMapsIcon, .starredMaps.active .exploreMapsIcon {
background-position: -96px -32px; background-position: -96px -32px;
} }
.sharedMaps:hover .navBarIcon, .sharedMaps.active .navBarIcon { .sharedMaps:hover .exploreMapsIcon, .sharedMaps.active .exploreMapsIcon {
background-position: -128px -32px; background-position: -128px -32px;
} }
.notificationsLink:hover .navBarIcon, .notificationsLink.active .navBarIcon { .notificationsLink:hover .exploreMapsIcon, .notificationsLink.active .exploreMapsIcon {
background-position-y: -32px; background-position-y: -32px;
} }

View file

@ -32,7 +32,7 @@
/* Smartphones (portrait and landscape) ----------- the minimum space that two map cards can fit side by side */ /* Smartphones (portrait and landscape) ----------- the minimum space that two map cards can fit side by side */
@media only screen and (max-width : 504px) { @media only screen and (max-width : 504px) {
.upperLeftUI, .upperRightUI, .openCheatsheet, .mapInfoIcon, .feedback-icon, .chat-box, #navBar { .upperLeftUI, .upperRightUI, .openCheatsheet, .mapInfoIcon, .feedback-icon, .chat-box, #exploreMapsHeader {
display: none !important; display: none !important;
} }

View file

@ -1,7 +1,4 @@
$notifications-border-color: #DDDDDD;
$notifications-hover-color: #F6F6F6;
$unread_notifications_dot_size: 8px; $unread_notifications_dot_size: 8px;
.unread-notifications-dot { .unread-notifications-dot {
width: $unread_notifications_dot_size; width: $unread_notifications_dot_size;
height: $unread_notifications_dot_size; height: $unread_notifications_dot_size;
@ -16,72 +13,13 @@ $unread_notifications_dot_size: 8px;
.notificationsIcon { .notificationsIcon {
position: relative; position: relative;
} }
.notificationsBox {
position: absolute;
background: #FFFFFF;
border-radius: 2px;
width: 350px;
right: 0;
top: 50px;
box-shadow: 0 3px 6px rgba(0,0,0,0.16);
border: 1px solid $notifications-border-color;
.notificationsBoxTriangle {
min-width: 0 !important;
display: block;
position: absolute;
right: 48px;
width: 20px !important;
height: 20px !important;
margin-left: -10px;
top: -11px;
border-left: 1px solid $notifications-border-color;
border-top: 1px solid $notifications-border-color;
border-bottom: 0 !important;
border-right: 0 !important;
background-color: #fff;
transform: rotate(45deg);
-webkit-transform: rotate(45deg);
-ms-transform: rotate(45deg);
}
ul.notifications {
max-height: 500px;
overflow-y: auto;
.notification {
font-size: 13px;
.notification-body {
border-bottom: 1px solid $notifications-border-color;
}
}
.notificationsEmpty {
font-family: din-regular, helvetica, sans-serif;
margin: 50px 10px;
text-align: center;
}
}
.notificationsBoxSeeAll {
display: block;
width: 100%;
text-align: center;
padding: 6px 0;
font-family: din-regular, helvetica, sans-serif;
border-top: 1px solid rgba(0, 0, 0, 0.1);
&:hover {
color: #333;
background: $notifications-hover-color;
}
}
}
} }
.controller-notifications { .controller-notifications {
ul.notifications {
list-style: none;
}
.notificationPage, .notificationPage,
.notificationsPage { .notificationsPage {
font-family: 'din-regular', Sans-Serif; font-family: 'din-regular', Sans-Serif;
@ -109,6 +47,86 @@ $unread_notifications_dot_size: 8px;
.emptyInbox { .emptyInbox {
padding-top: 15px; padding-top: 15px;
} }
.notification {
padding: 10px;
position: relative;
&:hover {
background: #F6F6F6;
.notification-read-unread {
display:block;
}
.notification-date {
display: none;
}
}
& > a {
float: left;
width: 85%;
box-sizing: border-box;
padding-right: 10px;
}
.notification-actor {
float: left;
img {
width: 32px;
height: 32px;
border-radius: 16px;
}
}
.notification-body {
margin-left: 50px;
line-height: 20px;
.in-bold {
font-family: 'din-medium', Sans-Serif;
}
.action {
background: #4fb5c0;
color: #FFF;
padding: 2px 6px;
border-radius: 3px;
display: inline-block;
margin: 5px 0;
}
}
.notification-date {
position: absolute;
top: 50%;
right: 10px;
color: #607d8b;
font-size: 13px;
line-height: 13px;
margin-top: -6px;
}
.notification-read-unread {
display: none;
float: left;
width: 15%;
a {
position: absolute;
top: 50%;
margin-top: -10px;
text-align: center;
}
}
&.unread {
background: #EEE;
}
}
} }
@ -145,93 +163,3 @@ $unread_notifications_dot_size: 8px;
} }
} }
} }
ul.notifications {
list-style: none;
li:nth-last-child(2) {
.notification-body {
border-bottom: none !important;
}
}
}
.notification {
padding: 10px 10px 0 10px;
position: relative;
font-family: 'din-regular', Sans-Serif;
&.unread {
background: #EEE;
}
&:hover {
background: $notifications-hover-color;
.notification-read-unread {
display:block;
}
.notification-date {
display: none;
}
}
& > a {
float: left;
width: 85%;
box-sizing: border-box;
padding-right: 10px;
}
.notification-actor {
float: left;
img {
width: 32px;
height: 32px;
border-radius: 16px;
}
}
.notification-body {
margin-left: 50px;
line-height: 20px;
padding-bottom: 10px;
.in-bold {
font-family: 'din-medium', Sans-Serif;
}
.action {
background: #4fb5c0;
color: #FFF;
padding: 2px 6px;
border-radius: 3px;
display: inline-block;
margin: 5px 0;
}
}
.notification-date {
position: absolute;
top: 50%;
right: 10px;
color: #607d8b;
margin-top: -6px;
}
.notification-read-unread {
display: none;
float: left;
width: 15%;
a, div {
position: absolute;
top: 50%;
margin-top: -10px;
text-align: center;
cursor: pointer;
}
}
}

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module ApplicationCable module ApplicationCable
class Channel < ActionCable::Channel::Base class Channel < ActionCable::Channel::Base
end end

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module ApplicationCable module ApplicationCable
class Connection < ActionCable::Connection::Base class Connection < ActionCable::Connection::Base
identified_by :current_user identified_by :current_user

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
class MapChannel < ApplicationCable::Channel class MapChannel < ApplicationCable::Channel
# Called when the consumer has successfully # Called when the consumer has successfully
# become a subscriber of this channel. # become a subscriber of this channel.

View file

@ -1,12 +1,11 @@
# frozen_string_literal: true # frozen_string_literal: true
class AccessController < ApplicationController class AccessController < ApplicationController
before_action :require_user, only: %i[access access_request before_action :require_user, only: [:access, :access_request,
approve_access approve_access_post :approve_access, :approve_access_post,
deny_access deny_access_post request_access] :deny_access, :deny_access_post, :request_access]
before_action :set_map, only: %i[access access_request before_action :set_map, only: [:access, :access_request,
approve_access approve_access_post :approve_access, :approve_access_post,
deny_access deny_access_post request_access] :deny_access, :deny_access_post, :request_access]
after_action :verify_authorized after_action :verify_authorized
# GET maps/:id/request_access # GET maps/:id/request_access

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module Api module Api
module V1 module V1
class DeprecatedController < ApplicationController class DeprecatedController < ApplicationController

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module Api module Api
module V2 module V2
class MappingsController < WithUpdatesController class MappingsController < WithUpdatesController

View file

@ -1,10 +1,9 @@
# frozen_string_literal: true # frozen_string_literal: true
module Api module Api
module V2 module V2
class MapsController < WithUpdatesController class MapsController < WithUpdatesController
def searchable_columns def searchable_columns
%i[name desc] [:name, :desc]
end end
def apply_filters(collection) def apply_filters(collection)

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module Api module Api
module V2 module V2
class MetacodesController < RestfulController class MetacodesController < RestfulController

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module Api module Api
module V2 module V2
class RestfulController < ActionController::Base class RestfulController < ActionController::Base
@ -8,7 +7,7 @@ module Api
snorlax_used_rest! snorlax_used_rest!
before_action :load_resource, only: %i[show update destroy] before_action :load_resource, only: [:show, :update, :destroy]
after_action :verify_authorized after_action :verify_authorized
def index def index
@ -92,7 +91,7 @@ module Api
end end
def doorkeeper_user def doorkeeper_user
return if doorkeeper_token.blank? return unless doorkeeper_token.present?
doorkeeper_render_error unless valid_doorkeeper_token? doorkeeper_render_error unless valid_doorkeeper_token?
@doorkeeper_user ||= User.find(doorkeeper_token.resource_owner_id) @doorkeeper_user ||= User.find(doorkeeper_token.resource_owner_id)
end end

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module Api module Api
module V2 module V2
class SessionsController < ApplicationController class SessionsController < ApplicationController

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module Api module Api
module V2 module V2
class StarsController < RestfulController class StarsController < RestfulController

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module Api module Api
module V2 module V2
class SynapsesController < WithUpdatesController class SynapsesController < WithUpdatesController

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module Api module Api
module V2 module V2
class TokensController < RestfulController class TokensController < RestfulController

View file

@ -1,10 +1,9 @@
# frozen_string_literal: true # frozen_string_literal: true
module Api module Api
module V2 module V2
class TopicsController < WithUpdatesController class TopicsController < WithUpdatesController
def searchable_columns def searchable_columns
%i[name desc link] [:name, :desc, :link]
end end
end end
end end

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module Api module Api
module V2 module V2
class UsersController < RestfulController class UsersController < RestfulController

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module Api module Api
module V2 module V2
class WithUpdatesController < RestfulController class WithUpdatesController < RestfulController

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
class ApplicationController < ActionController::Base class ApplicationController < ActionController::Base
include ApplicationHelper include ApplicationHelper
include Pundit include Pundit

View file

@ -1,7 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class ExploreController < ApplicationController class ExploreController < ApplicationController
before_action :require_authentication, only: %i[mine shared starred] before_action :require_authentication, only: [:mine, :shared, :starred]
before_action :authorize_explore before_action :authorize_explore
after_action :verify_authorized after_action :verify_authorized
after_action :verify_policy_scoped after_action :verify_policy_scoped

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
# bad code that should be checked over before entering one of the # bad code that should be checked over before entering one of the
# nice files from the right side of this repo # nice files from the right side of this repo
class HacksController < ApplicationController class HacksController < ApplicationController

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
class MainController < ApplicationController class MainController < ApplicationController
before_action :authorize_main before_action :authorize_main
after_action :verify_authorized after_action :verify_authorized

View file

@ -1,7 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class MappingsController < ApplicationController class MappingsController < ApplicationController
before_action :require_user, only: %i[create update destroy] before_action :require_user, only: [:create, :update, :destroy]
after_action :verify_authorized, except: :index after_action :verify_authorized, except: :index
after_action :verify_policy_scoped, only: :index after_action :verify_policy_scoped, only: :index

View file

@ -1,10 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class MapsController < ApplicationController class MapsController < ApplicationController
before_action :require_user, only: %i[create update destroy events follow unfollow] before_action :require_user, only: [:create, :update, :destroy, :events, :follow, :unfollow]
before_action :set_map, only: %i[show conversation update destroy before_action :set_map, only: [:show, :conversation, :update, :destroy, :contains, :events, :export, :follow, :unfollow, :unfollow_from_email]
contains events export
follow unfollow unfollow_from_email]
after_action :verify_authorized after_action :verify_authorized
# GET maps/:id # GET maps/:id

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
class MessagesController < ApplicationController class MessagesController < ApplicationController
before_action :require_user, except: [:show] before_action :require_user, except: [:show]
after_action :verify_authorized after_action :verify_authorized

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
class MetacodeSetsController < ApplicationController class MetacodeSetsController < ApplicationController
before_action :require_admin before_action :require_admin

View file

@ -1,8 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class MetacodesController < ApplicationController class MetacodesController < ApplicationController
before_action :require_admin, except: %i[index show] before_action :require_admin, except: [:index, :show]
before_action :set_metacode, only: %i[edit update] before_action :set_metacode, only: [:edit, :update]
# GET /metacodes # GET /metacodes
# GET /metacodes.json # GET /metacodes.json

View file

@ -1,23 +1,18 @@
# frozen_string_literal: true # frozen_string_literal: true
class NotificationsController < ApplicationController class NotificationsController < ApplicationController
before_action :set_receipts, only: %i[index show mark_read mark_unread] before_action :set_receipts, only: [:index, :show, :mark_read, :mark_unread]
before_action :set_notification, only: %i[show mark_read mark_unread] before_action :set_notification, only: [:show, :mark_read, :mark_unread]
before_action :set_receipt, only: %i[show mark_read mark_unread] before_action :set_receipt, only: [:show, :mark_read, :mark_unread]
def index def index
@notifications = current_user.mailbox.notifications.page(params[:page]).per(25) @notifications = current_user.mailbox.notifications.page(params[:page]).per(25)
respond_to do |format| respond_to do |format|
format.html format.html
format.json do format.json do
notifications = @notifications.map do |notification| render json: @notifications.map do |notification|
receipt = @receipts.find_by(notification_id: notification.id) receipt = @receipts.find_by(notification_id: notification.id)
NotificationDecorator.decorate(notification, receipt) notification.as_json.merge(is_read: receipt.is_read)
end
if !notifications.empty?
render json: notifications
else
render json: [].to_json
end end
end end
end end
@ -28,18 +23,20 @@ class NotificationsController < ApplicationController
respond_to do |format| respond_to do |format|
format.html do format.html do
case @notification.notification_code case @notification.notification_code
when MAP_ACCESS_APPROVED, MAP_INVITE_TO_EDIT when MAP_ACCESS_APPROVED, MAP_INVITE_TO_EDIT
redirect_to map_path(@notification.notified_object.map) redirect_to map_path(@notification.notified_object.map)
when TOPIC_ADDED_TO_MAP when TOPIC_ADDED_TO_MAP
redirect_to map_path(@notification.notified_object.map) redirect_to map_path(@notification.notified_object.map)
when TOPIC_CONNECTED_1 when TOPIC_CONNECTED_1
redirect_to topic_path(@notification.notified_object.topic1) redirect_to topic_path(@notification.notified_object.topic1)
when TOPIC_CONNECTED_2 when TOPIC_CONNECTED_2
redirect_to topic_path(@notification.notified_object.topic2) redirect_to topic_path(@notification.notified_object.topic2)
end end
end end
format.json do format.json do
render json: NotificationDecorator.decorate(@notification, @receipt) render json: @notification.as_json.merge(
is_read: @receipt.is_read
)
end end
end end
end end
@ -49,7 +46,9 @@ class NotificationsController < ApplicationController
respond_to do |format| respond_to do |format|
format.js format.js
format.json do format.json do
render json: NotificationDecorator.decorate(@notification, @receipt) render json: @notification.as_json.merge(
is_read: @receipt.is_read
)
end end
end end
end end
@ -59,7 +58,9 @@ class NotificationsController < ApplicationController
respond_to do |format| respond_to do |format|
format.js format.js
format.json do format.json do
render json: NotificationDecorator.decorate(@notification, @receipt) render json: @notification.as_json.merge(
is_read: @receipt.is_read
)
end end
end end
end end

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
class SearchController < ApplicationController class SearchController < ApplicationController
include TopicsHelper include TopicsHelper
include MapsHelper include MapsHelper
@ -8,7 +7,7 @@ class SearchController < ApplicationController
before_action :authorize_search before_action :authorize_search
after_action :verify_authorized after_action :verify_authorized
after_action :verify_policy_scoped, only: %i[maps mappers synapses topics] after_action :verify_policy_scoped, only: [:maps, :mappers, :synapses, :topics]
# get /search/topics?term=SOMETERM # get /search/topics?term=SOMETERM
def topics def topics
@ -141,13 +140,13 @@ class SearchController < ApplicationController
topic1id = params[:topic1id] topic1id = params[:topic1id]
topic2id = params[:topic2id] topic2id = params[:topic2id]
if term.present? if term && !term.empty?
@synapses = policy_scope(Synapse) @synapses = policy_scope(Synapse)
.where('LOWER("desc") like ?', '%' + term.downcase.strip + '%') .where('LOWER("desc") like ?', '%' + term.downcase.strip + '%')
.order('"desc"') .order('"desc"')
@synapses = @synapses.uniq(&:desc) @synapses = @synapses.uniq(&:desc)
elsif topic1id.present? elsif topic1id && !topic1id.empty?
one = policy_scope(Synapse).where(topic1_id: topic1id, topic2_id: topic2id) one = policy_scope(Synapse).where(topic1_id: topic1id, topic2_id: topic2id)
two = policy_scope(Synapse).where(topic2_id: topic1id, topic1_id: topic2id) two = policy_scope(Synapse).where(topic2_id: topic1id, topic1_id: topic2id)
@synapses = one + two @synapses = one + two

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
class StarsController < ApplicationController class StarsController < ApplicationController
before_action :require_user before_action :require_user
before_action :set_map before_action :set_map

View file

@ -1,9 +1,8 @@
# frozen_string_literal: true # frozen_string_literal: true
class SynapsesController < ApplicationController class SynapsesController < ApplicationController
include TopicsHelper include TopicsHelper
before_action :require_user, only: %i[create update destroy] before_action :require_user, only: [:create, :update, :destroy]
after_action :verify_authorized, except: :index after_action :verify_authorized, except: :index
after_action :verify_policy_scoped, only: :index after_action :verify_policy_scoped, only: :index

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
class TokensController < ApplicationController class TokensController < ApplicationController
before_action :require_user, only: [:new] before_action :require_user, only: [:new]

View file

@ -1,12 +1,11 @@
# frozen_string_literal: true # frozen_string_literal: true
class TopicsController < ApplicationController class TopicsController < ApplicationController
include TopicsHelper include TopicsHelper
before_action :require_user, only: %i[create update destroy follow unfollow] before_action :require_user, only: [:create, :update, :destroy, :follow, :unfollow]
before_action :set_topic, only: %i[show update relative_numbers before_action :set_topic, only: [:show, :update, :relative_numbers,
relatives network destroy :relatives, :network, :destroy,
follow unfollow unfollow_from_email] :follow, :unfollow, :unfollow_from_email]
after_action :verify_authorized, except: :autocomplete_topic after_action :verify_authorized, except: :autocomplete_topic
respond_to :html, :js, :json respond_to :html, :js, :json
@ -14,7 +13,7 @@ class TopicsController < ApplicationController
# GET /topics/autocomplete_topic # GET /topics/autocomplete_topic
def autocomplete_topic def autocomplete_topic
term = params[:term] term = params[:term]
if term.present? if term && !term.empty?
topics = policy_scope(Topic) topics = policy_scope(Topic)
.where('LOWER("name") like ?', term.downcase + '%') .where('LOWER("name") like ?', term.downcase + '%')
.order('"name"') .order('"name"')

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module Users module Users
class PasswordsController < Devise::PasswordsController class PasswordsController < Devise::PasswordsController
protected protected

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module Users module Users
class RegistrationsController < Devise::RegistrationsController class RegistrationsController < Devise::RegistrationsController
before_action :configure_sign_up_params, only: [:create] before_action :configure_sign_up_params, only: [:create]
@ -30,7 +29,7 @@ module Users
end end
def configure_sign_up_params def configure_sign_up_params
devise_parameter_sanitizer.permit(:sign_up, keys: %i[name joinedwithcode]) devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :joinedwithcode])
end end
def configure_account_update_params def configure_account_update_params

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module Users module Users
class SessionsController < Devise::SessionsController class SessionsController < Devise::SessionsController
after_action :store_location, only: [:new] after_action :store_location, only: [:new]

View file

@ -1,7 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class UsersController < ApplicationController class UsersController < ApplicationController
before_action :require_user, only: %i[edit update updatemetacodes update_metacode_focus] before_action :require_user, only: [:edit, :update, :updatemetacodes, :update_metacode_focus]
respond_to :html, :json respond_to :html, :json
@ -24,15 +23,15 @@ class UsersController < ApplicationController
if user_params[:password] == '' && user_params[:password_confirmation] == '' if user_params[:password] == '' && user_params[:password_confirmation] == ''
# not trying to change the password # not trying to change the password
if @user.update_attributes(user_params.except(:password, :password_confirmation)) if @user.update_attributes(user_params.except(:password, :password_confirmation))
update_follow_settings(@user, params[:settings]) update_follow_settings(@user, params[:settings]) if is_tester(@user)
@user.image = nil if params[:remove_image] == '1' @user.image = nil if params[:remove_image] == '1'
@user.save @user.save
bypass_sign_in(@user) sign_in(@user, bypass: true)
respond_to do |format| respond_to do |format|
format.html { redirect_to root_url, notice: 'Settings updated' } format.html { redirect_to root_url, notice: 'Settings updated' }
end end
else else
bypass_sign_in(@user) sign_in(@user, bypass: true)
respond_to do |format| respond_to do |format|
format.html { redirect_to edit_user_path(@user), notice: @user.errors.to_a[0] } format.html { redirect_to edit_user_path(@user), notice: @user.errors.to_a[0] }
end end
@ -42,7 +41,7 @@ class UsersController < ApplicationController
correct_pass = @user.valid_password?(params[:current_password]) correct_pass = @user.valid_password?(params[:current_password])
if correct_pass && @user.update_attributes(user_params) if correct_pass && @user.update_attributes(user_params)
update_follow_settings(@user, params[:settings]) update_follow_settings(@user, params[:settings]) if is_tester(@user)
@user.image = nil if params[:remove_image] == '1' @user.image = nil if params[:remove_image] == '1'
@user.save @user.save
sign_in(@user, bypass: true) sign_in(@user, bypass: true)
@ -101,7 +100,7 @@ class UsersController < ApplicationController
@user.settings.metacode_focus = params[:value] @user.settings.metacode_focus = params[:value]
@user.save @user.save
respond_to do |format| respond_to do |format|
format.json { render json: { success: 'success' } } format.json { render json: { success: "success" }}
end end
end end

View file

@ -1,51 +0,0 @@
# frozen_string_literal: true
class NotificationDecorator
class << self
def decorate(notification, receipt)
result = {
id: notification.id,
type: notification.notification_code,
subject: notification.subject,
is_read: receipt.is_read,
created_at: notification.created_at,
actor: notification.sender,
data: {
object: notification.notified_object
}
}
case notification.notification_code
when MAP_ACCESS_APPROVED, MAP_ACCESS_REQUEST, MAP_INVITE_TO_EDIT
map = notification.notified_object&.map
result[:data][:map] = {
id: map&.id,
name: map&.name
}
when TOPIC_ADDED_TO_MAP
topic = notification.notified_object&.eventable
map = notification.notified_object&.map
result[:data][:topic] = {
id: topic&.id,
name: topic&.name
}
result[:data][:map] = {
id: map&.id,
name: map&.name
}
when TOPIC_CONNECTED_1, TOPIC_CONNECTED_2
topic1 = notification.notified_object&.topic1
topic2 = notification.notified_object&.topic2
result[:data][:topic1] = {
id: topic1&.id,
name: topic1&.name
}
result[:data][:topic2] = {
id: topic2&.id,
name: topic2&.name
}
end
result
end
end
end

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module ApplicationHelper module ApplicationHelper
def invite_link def invite_link
"#{request.base_url}/join" + (current_user ? "?code=#{current_user.code}" : '') "#{request.base_url}/join" + (current_user ? "?code=#{current_user.code}" : '')

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module ContentHelper module ContentHelper
def resource_name def resource_name
:user :user

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module DeviseHelper module DeviseHelper
def devise_error_messages! def devise_error_messages!
resource.errors.to_a[0] resource.errors.to_a[0]

View file

@ -1,4 +1,3 @@
# frozen_string_literal: true # frozen_string_literal: true
module InMetacodeSetsHelper module InMetacodeSetsHelper
end end

View file

@ -1,4 +1,3 @@
# frozen_string_literal: true # frozen_string_literal: true
module MainHelper module MainHelper
end end

View file

@ -1,5 +1,3 @@
# frozen_string_literal: true
module MapMailerHelper module MapMailerHelper
def access_approved_subject(map) def access_approved_subject(map)
map.name + ' - access approved' map.name + ' - access approved'

View file

@ -1,4 +1,3 @@
# frozen_string_literal: true # frozen_string_literal: true
module MappingHelper module MappingHelper
end end

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module MapsHelper module MapsHelper
# JSON autocomplete format for typeahead # JSON autocomplete format for typeahead
def autocomplete_map_array_json(maps) def autocomplete_map_array_json(maps)

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module MetacodesHelper module MetacodesHelper
def metacodeset def metacodeset
metacodes = current_user.settings.metacodes metacodes = current_user.settings.metacodes

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module SynapsesHelper module SynapsesHelper
## this one is for building our custom JSON autocomplete format for typeahead ## this one is for building our custom JSON autocomplete format for typeahead
def autocomplete_synapse_generic_json(unique) def autocomplete_synapse_generic_json(unique)

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module TopicMailerHelper module TopicMailerHelper
def added_to_map_subject(topic, map) def added_to_map_subject(topic, map)
topic.name + ' was added to map ' + map.name topic.name + ' was added to map ' + map.name

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module TopicsHelper module TopicsHelper
## this one is for building our custom JSON autocomplete format for typeahead ## this one is for building our custom JSON autocomplete format for typeahead
def autocomplete_array_json(topics) def autocomplete_array_json(topics)
@ -17,7 +16,7 @@ module TopicsHelper
rtype: is_map ? 'map' : 'topic', rtype: is_map ? 'map' : 'topic',
inmaps: is_map ? [] : t.inmaps(current_user), inmaps: is_map ? [] : t.inmaps(current_user),
inmapsLinks: is_map ? [] : t.inmaps_links(current_user), inmapsLinks: is_map ? [] : t.inmapsLinks(current_user),
type: is_map ? metamap_metacode.name : t.metacode.name, type: is_map ? metamap_metacode.name : t.metacode.name,
typeImageURL: is_map ? metamap_metacode.icon : t.metacode.icon, typeImageURL: is_map ? metamap_metacode.icon : t.metacode.icon,
mapCount: is_map ? 0 : t.maps.count, mapCount: is_map ? 0 : t.maps.count,

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module UsersHelper module UsersHelper
# build custom json autocomplete for typeahead # build custom json autocomplete for typeahead
def autocomplete_user_array_json(users) def autocomplete_user_array_json(users)

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
class ApplicationMailer < ActionMailer::Base class ApplicationMailer < ActionMailer::Base
default from: 'team@metamaps.cc' default from: 'team@metamaps.cc'
layout 'mailer' layout 'mailer'
@ -7,24 +6,24 @@ class ApplicationMailer < ActionMailer::Base
class << self class << self
def mail_for_notification(notification) def mail_for_notification(notification)
case notification.notification_code case notification.notification_code
when MAP_ACCESS_REQUEST when MAP_ACCESS_REQUEST
request = notification.notified_object request = notification.notified_object
MapMailer.access_request(request) MapMailer.access_request(request)
when MAP_ACCESS_APPROVED when MAP_ACCESS_APPROVED
request = notification.notified_object request = notification.notified_object
MapMailer.access_approved(request) MapMailer.access_approved(request)
when MAP_INVITE_TO_EDIT when MAP_INVITE_TO_EDIT
user_map = notification.notified_object user_map = notification.notified_object
MapMailer.invite_to_edit(user_map) MapMailer.invite_to_edit(user_map)
when TOPIC_ADDED_TO_MAP when TOPIC_ADDED_TO_MAP
event = notification.notified_object event = notification.notified_object
TopicMailer.added_to_map(event, notification.recipients[0]) TopicMailer.added_to_map(event, notification.recipients[0])
when TOPIC_CONNECTED_1 when TOPIC_CONNECTED_1
synapse = notification.notified_object synapse = notification.notified_object
TopicMailer.connected(synapse, synapse.topic1, notification.recipients[0]) TopicMailer.connected(synapse, synapse.topic1, notification.recipients[0])
when TOPIC_CONNECTED_2 when TOPIC_CONNECTED_2
synapse = notification.notified_object synapse = notification.notified_object
TopicMailer.connected(synapse, synapse.topic2, notification.recipients[0]) TopicMailer.connected(synapse, synapse.topic2, notification.recipients[0])
end end
end end
end end

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
class MapActivityMailer < ApplicationMailer class MapActivityMailer < ApplicationMailer
default from: 'team@metamaps.cc' default from: 'team@metamaps.cc'

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
class MapMailer < ApplicationMailer class MapMailer < ApplicationMailer
include MapMailerHelper include MapMailerHelper
default from: 'team@metamaps.cc' default from: 'team@metamaps.cc'

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
class TopicMailer < ApplicationMailer class TopicMailer < ApplicationMailer
include TopicMailerHelper include TopicMailerHelper
default from: 'team@metamaps.cc' default from: 'team@metamaps.cc'

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
class AccessRequest < ApplicationRecord class AccessRequest < ApplicationRecord
belongs_to :user belongs_to :user
belongs_to :map belongs_to :map

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
class ApplicationRecord < ActiveRecord::Base class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true self.abstract_class = true
end end

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
class Attachment < ApplicationRecord class Attachment < ApplicationRecord
belongs_to :attachable, polymorphic: true belongs_to :attachable, polymorphic: true

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module Attachable module Attachable
extend ActiveSupport::Concern extend ActiveSupport::Concern

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module Routing module Routing
extend ActiveSupport::Concern extend ActiveSupport::Concern
include Rails.application.routes.url_helpers include Rails.application.routes.url_helpers

View file

@ -1,17 +1,16 @@
# frozen_string_literal: true # frozen_string_literal: true
class Event < ApplicationRecord class Event < ApplicationRecord
KINDS = %w[user_present_on_map user_not_present_on_map KINDS = %w(user_present_on_map user_not_present_on_map
conversation_started_on_map conversation_started_on_map
topic_added_to_map topic_moved_on_map topic_removed_from_map topic_added_to_map topic_moved_on_map topic_removed_from_map
synapse_added_to_map synapse_removed_from_map synapse_added_to_map synapse_removed_from_map
topic_updated synapse_updated].freeze topic_updated synapse_updated).freeze
belongs_to :eventable, polymorphic: true belongs_to :eventable, polymorphic: true
belongs_to :map belongs_to :map
belongs_to :user belongs_to :user
scope :chronologically, (-> { order('created_at asc') }) scope :chronologically, -> { order('created_at asc') }
after_create :notify_webhooks!, if: :map after_create :notify_webhooks!, if: :map

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module Events module Events
class ConversationStartedOnMap < Event class ConversationStartedOnMap < Event
# after_create :notify_users! # after_create :notify_users!

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module Events module Events
class SynapseAddedToMap < Event class SynapseAddedToMap < Event
# after_create :notify_users! # after_create :notify_users!

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module Events module Events
class SynapseRemovedFromMap < Event class SynapseRemovedFromMap < Event
# after_create :notify_users! # after_create :notify_users!

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module Events module Events
class SynapseUpdated < Event class SynapseUpdated < Event
# after_create :notify_users! # after_create :notify_users!

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module Events module Events
class TopicAddedToMap < Event class TopicAddedToMap < Event
after_create :notify_users! after_create :notify_users!

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module Events module Events
class TopicMovedOnMap < Event class TopicMovedOnMap < Event
# after_create :notify_users! # after_create :notify_users!

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module Events module Events
class TopicRemovedFromMap < Event class TopicRemovedFromMap < Event
# after_create :notify_users! # after_create :notify_users!

View file

@ -1,8 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
module Events module Events
class TopicUpdated < Event class TopicUpdated < Event
# after_create :notify_users! #after_create :notify_users!
def self.publish!(topic, user, meta) def self.publish!(topic, user, meta)
create!(kind: 'topic_updated', create!(kind: 'topic_updated',

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module Events module Events
class UserNotPresentOnMap < Event class UserNotPresentOnMap < Event
# after_create :notify_users! # after_create :notify_users!

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
module Events module Events
class UserPresentOnMap < Event class UserPresentOnMap < Event
# after_create :notify_users! # after_create :notify_users!

View file

@ -1,6 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class Follow < ApplicationRecord class Follow < ApplicationRecord
belongs_to :user belongs_to :user
belongs_to :followed, polymorphic: true belongs_to :followed, polymorphic: true
has_one :follow_reason, dependent: :destroy has_one :follow_reason, dependent: :destroy
@ -11,11 +11,9 @@ class Follow < ApplicationRecord
after_create :add_subsetting after_create :add_subsetting
scope :active, (-> { where(muted: false) })
private private
def add_subsetting def add_subsetting
FollowReason.create!(follow: self) follow_reason = FollowReason.create!(follow: self)
end end
end end

View file

@ -1,7 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class FollowReason < ApplicationRecord class FollowReason < ApplicationRecord
REASONS = %w[created commented contributed followed shared_on starred].freeze REASONS = %w(created commented contributed followed shared_on starred).freeze
belongs_to :follow belongs_to :follow

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
class InMetacodeSet < ApplicationRecord class InMetacodeSet < ApplicationRecord
belongs_to :metacode, class_name: 'Metacode', foreign_key: 'metacode_id' belongs_to :metacode, class_name: 'Metacode', foreign_key: 'metacode_id'
belongs_to :metacode_set, class_name: 'MetacodeSet', foreign_key: 'metacode_set_id' belongs_to :metacode_set, class_name: 'MetacodeSet', foreign_key: 'metacode_set_id'

View file

@ -1,7 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class Map < ApplicationRecord class Map < ApplicationRecord
ATTRS_TO_WATCH = %w[name desc permission].freeze ATTRS_TO_WATCH = %w(name desc permission).freeze
belongs_to :user belongs_to :user
belongs_to :source, class_name: :Map belongs_to :source, class_name: :Map
@ -16,7 +15,7 @@ class Map < ApplicationRecord
has_many :messages, as: :resource, dependent: :destroy has_many :messages, as: :resource, dependent: :destroy
has_many :stars, dependent: :destroy has_many :stars, dependent: :destroy
has_many :follows, as: :followed, dependent: :destroy has_many :follows, as: :followed, dependent: :destroy
has_many :followers, through: :follows, source: :user has_many :followers, :through => :follows, source: :user
has_many :access_requests, dependent: :destroy has_many :access_requests, dependent: :destroy
has_many :user_maps, dependent: :destroy has_many :user_maps, dependent: :destroy
@ -43,7 +42,6 @@ class Map < ApplicationRecord
after_create :after_created after_create :after_created
after_update :after_updated after_update :after_updated
after_save :update_deferring_topics_and_synapses, if: :permission_changed? after_save :update_deferring_topics_and_synapses, if: :permission_changed?
before_destroy :before_destroyed
delegate :count, to: :topics, prefix: :topic # same as `def topic_count; topics.count; end` delegate :count, to: :topics, prefix: :topic # same as `def topic_count; topics.count; end`
delegate :count, to: :synapses, prefix: :synapse delegate :count, to: :synapses, prefix: :synapse
@ -90,10 +88,10 @@ class Map < ApplicationRecord
def as_json(_options = {}) def as_json(_options = {})
json = super( json = super(
methods: %i[user_name user_image star_count topic_count synapse_count methods: [:user_name, :user_image, :star_count, :topic_count, :synapse_count,
contributor_count collaborator_ids screenshot_url], :contributor_count, :collaborator_ids, :screenshot_url],
except: %i[screenshot_content_type screenshot_file_size screenshot_file_name except: [:screenshot_content_type, :screenshot_file_size, :screenshot_file_name,
screenshot_updated_at] :screenshot_updated_at]
) )
json[:created_at_clean] = created_at_str json[:created_at_clean] = created_at_str
json[:updated_at_clean] = updated_at_str json[:updated_at_clean] = updated_at_str
@ -143,7 +141,7 @@ class Map < ApplicationRecord
protected protected
def after_created def after_created
FollowService.follow(self, user, 'created') FollowService.follow(self, self.user, 'created')
# notify users following the map creator # notify users following the map creator
end end
@ -153,16 +151,11 @@ class Map < ApplicationRecord
end end
def after_updated_async def after_updated_async
return unless ATTRS_TO_WATCH.any? { |k| changed_attributes.key?(k) } if ATTRS_TO_WATCH.any? { |k| changed_attributes.key?(k) }
FollowService.follow(self, updated_by, 'contributed') FollowService.follow(self, updated_by, 'contributed')
# NotificationService.notify_followers(self, 'map_updated', changed_attributes) # NotificationService.notify_followers(self, 'map_updated', changed_attributes)
# or better yet publish an event # or better yet publish an event
end
handle_asynchronously :after_updated_async
def before_destroyed
Map.where(source_id: id).find_each do |forked_map|
forked_map.update(source_id: nil)
end end
end end
handle_asynchronously :after_updated_async
end end

View file

@ -1,8 +1,7 @@
# frozen_string_literal: true # frozen_string_literal: true
class Mapping < ApplicationRecord class Mapping < ApplicationRecord
scope :topicmapping, (-> { where(mappable_type: :Topic) }) scope :topicmapping, -> { where(mappable_type: :Topic) }
scope :synapsemapping, (-> { where(mappable_type: :Synapse) }) scope :synapsemapping, -> { where(mappable_type: :Synapse) }
belongs_to :mappable, polymorphic: true belongs_to :mappable, polymorphic: true
belongs_to :map, class_name: 'Map', foreign_key: 'map_id', touch: true belongs_to :map, class_name: 'Map', foreign_key: 'map_id', touch: true
@ -25,7 +24,7 @@ class Mapping < ApplicationRecord
end end
def as_json(_options = {}) def as_json(_options = {})
super(methods: %i[user_name user_image]) super(methods: [:user_name, :user_image])
end end
def after_created def after_created
@ -38,8 +37,8 @@ class Mapping < ApplicationRecord
'map_' + map.id.to_s, 'map_' + map.id.to_s,
type: 'synapseAdded', type: 'synapseAdded',
synapse: mappable.filtered, synapse: mappable.filtered,
topic1: mappable.topic1&.filtered, topic1: mappable.topic1.filtered,
topic2: mappable.topic2&.filtered, topic2: mappable.topic2.filtered,
mapping_id: id mapping_id: id
) )
meta = { 'mapping_id': id } meta = { 'mapping_id': id }
@ -53,17 +52,17 @@ class Mapping < ApplicationRecord
handle_asynchronously :after_created_async handle_asynchronously :after_created_async
def after_updated def after_updated
return unless (mappable_type == 'Topic') && (xloc_changed? || yloc_changed?) if (mappable_type == 'Topic') && (xloc_changed? || yloc_changed?)
meta = { 'x': xloc, 'y': yloc, 'mapping_id': id } meta = { 'x': xloc, 'y': yloc, 'mapping_id': id }
Events::TopicMovedOnMap.publish!(mappable, map, updated_by, meta) Events::TopicMovedOnMap.publish!(mappable, map, updated_by, meta)
ActionCable.server.broadcast('map_' + map.id.to_s, type: 'topicMoved', ActionCable.server.broadcast 'map_' + map.id.to_s, type: 'topicMoved', id: mappable.id, mapping_id: id, x: xloc, y: yloc
id: mappable.id, mapping_id: id, end
x: xloc, y: yloc)
end end
def after_updated_async def after_updated_async
return unless (mappable_type == 'Topic') && (xloc_changed? || yloc_changed?) if (mappable_type == 'Topic') && (xloc_changed? || yloc_changed?)
FollowService.follow(map, updated_by, 'contributed') FollowService.follow(map, updated_by, 'contributed')
end
end end
handle_asynchronously :after_updated_async handle_asynchronously :after_updated_async

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
class Message < ApplicationRecord class Message < ApplicationRecord
belongs_to :user belongs_to :user
belongs_to :resource, polymorphic: true belongs_to :resource, polymorphic: true
@ -7,14 +6,15 @@ class Message < ApplicationRecord
delegate :name, to: :user, prefix: true delegate :name, to: :user, prefix: true
after_create :after_created after_create :after_created
# after_create :after_created_async #after_create :after_created_async
def user_image def user_image
user.image.url user.image.url
end end
def as_json(_options = {}) def as_json(_options = {})
json = super(methods: %i[user_name user_image]) json = super(methods: [:user_name, :user_image])
json json
end end

View file

@ -1,16 +1,17 @@
# frozen_string_literal: true # frozen_string_literal: true
class Metacode < ApplicationRecord class Metacode < ApplicationRecord
has_many :in_metacode_sets has_many :in_metacode_sets
has_many :metacode_sets, through: :in_metacode_sets has_many :metacode_sets, through: :in_metacode_sets
has_many :topics has_many :topics
# This method associates the attribute ":aws_icon" with a file attachment # This method associates the attribute ":aws_icon" with a file attachment
has_attached_file :aws_icon, styles: { ninetysix: ['96x96#', :png] }, has_attached_file :aws_icon, styles: {
ninetysix: ['96x96#', :png]
},
default_url: 'https://s3.amazonaws.com/metamaps-assets/metacodes/generics/96px/gen_wildcard.png' default_url: 'https://s3.amazonaws.com/metamaps-assets/metacodes/generics/96px/gen_wildcard.png'
# Validate the attached icon is image/jpg, image/png, etc # Validate the attached icon is image/jpg, image/png, etc
validates_attachment_content_type :aws_icon, content_type: %r{\Aimage/.*\Z} validates_attachment_content_type :aws_icon, content_type: /\Aimage\/.*\Z/
validate :aws_xor_manual_icon validate :aws_xor_manual_icon
validate :manual_icon_https validate :manual_icon_https
@ -29,13 +30,15 @@ class Metacode < ApplicationRecord
def as_json(options = {}) def as_json(options = {})
default = super(options) default = super(options)
default[:icon] = icon default[:icon] = icon
default.except( default.except('aws_icon_file_name', 'aws_icon_content_type', 'aws_icon_file_size', 'aws_icon_updated_at', 'manual_icon')
'aws_icon_file_name', 'aws_icon_content_type', 'aws_icon_file_size', 'aws_icon_updated_at',
'manual_icon'
)
end end
def in_metacode_set(metacode_set) def hasSelected(user)
return true if user.settings.metacodes.include? id.to_s
false
end
def inMetacodeSet(metacode_set)
return true if metacode_sets.include? metacode_set return true if metacode_sets.include? metacode_set
false false
end end
@ -52,9 +55,10 @@ class Metacode < ApplicationRecord
end end
def manual_icon_https def manual_icon_https
return if manual_icon.blank? if manual_icon.present?
unless manual_icon.starts_with? 'https' unless manual_icon.starts_with? 'https'
errors.add(:base, 'Manual icon must begin with https') errors.add(:base, 'Manual icon must begin with https')
end
end end
end end
end end

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
class MetacodeSet < ApplicationRecord class MetacodeSet < ApplicationRecord
belongs_to :user belongs_to :user
has_many :in_metacode_sets has_many :in_metacode_sets

View file

@ -1,18 +1,13 @@
# frozen_string_literal: true # frozen_string_literal: true
class PermittedParams < Struct.new(:params)
class PermittedParams %w(map synapse topic mapping token).each do |kind|
%w[map synapse topic mapping token].each do |kind|
define_method(kind) do define_method(kind) do
permitted_attributes = send("#{kind}_attributes") permitted_attributes = send("#{kind}_attributes")
@params.require(kind).permit(*permitted_attributes) params.require(kind).permit(*permitted_attributes)
end end
alias_method :"api_#{kind}", kind.to_sym alias_method :"api_#{kind}", kind.to_sym
end end
def initialize(params)
@params = params
end
alias read_attribute_for_serialization send alias read_attribute_for_serialization send
def token_attributes def token_attributes
@ -20,18 +15,18 @@ class PermittedParams
end end
def map_attributes def map_attributes
%i[name desc permission arranged] [:name, :desc, :permission, :arranged]
end end
def synapse_attributes def synapse_attributes
%i[desc category weight permission topic1_id topic2_id] [:desc, :category, :weight, :permission, :topic1_id, :topic2_id]
end end
def topic_attributes def topic_attributes
%i[name desc link permission metacode_id] [:name, :desc, :link, :permission, :metacode_id]
end end
def mapping_attributes def mapping_attributes
%i[xloc yloc map_id mappable_type mappable_id] [:xloc, :yloc, :map_id, :mappable_type, :mappable_id]
end end
end end

View file

@ -1,12 +1,11 @@
# frozen_string_literal: true # frozen_string_literal: true
class Star < ActiveRecord::Base
class Star < ApplicationRecord
belongs_to :user belongs_to :user
belongs_to :map belongs_to :map
validates :map, uniqueness: { scope: :user, message: 'You have already starred this map' } validates :map, uniqueness: { scope: :user, message: 'You have already starred this map' }
# after_create :after_created_async #after_create :after_created_async
# before_destroy :before_destroyed #before_destroy :before_destroyed
protected protected

View file

@ -1,7 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class Synapse < ApplicationRecord class Synapse < ApplicationRecord
ATTRS_TO_WATCH = %w[desc category permission defer_to_map_id].freeze ATTRS_TO_WATCH = %w(desc category permission defer_to_map_id).freeze
belongs_to :user belongs_to :user
belongs_to :defer_to_map, class_name: 'Map', foreign_key: 'defer_to_map_id' belongs_to :defer_to_map, class_name: 'Map', foreign_key: 'defer_to_map_id'
@ -22,9 +21,9 @@ class Synapse < ApplicationRecord
validates :category, inclusion: { in: ['from-to', 'both'], allow_nil: true } validates :category, inclusion: { in: ['from-to', 'both'], allow_nil: true }
scope :for_topic, (lambda do |topic_id = nil| scope :for_topic, ->(topic_id = nil) {
where(topic1_id: topic_id).or(where(topic2_id: topic_id)) where(topic1_id: topic_id).or(where(topic2_id: topic_id))
end) }
before_create :set_perm_by_defer before_create :set_perm_by_defer
after_create :after_created_async after_create :after_created_async
@ -39,7 +38,7 @@ class Synapse < ApplicationRecord
def collaborator_ids def collaborator_ids
if defer_to_map if defer_to_map
defer_to_map.editors.reject { |mapper| mapper == user }.map(&:id) defer_to_map.editors.select { |mapper| mapper != user }.map(&:id)
else else
[] []
end end
@ -55,7 +54,7 @@ class Synapse < ApplicationRecord
end end
def as_json(_options = {}) def as_json(_options = {})
super(methods: %i[user_name user_image collaborator_ids]) super(methods: [:user_name, :user_image, :collaborator_ids])
end end
def as_rdf def as_rdf
@ -73,7 +72,7 @@ class Synapse < ApplicationRecord
protected protected
def set_perm_by_defer def set_perm_by_defer
defer_to_map&.permission permission = defer_to_map.permission if defer_to_map
end end
def after_created_async def after_created_async
@ -83,21 +82,21 @@ class Synapse < ApplicationRecord
handle_asynchronously :after_created_async handle_asynchronously :after_created_async
def after_updated def after_updated
return unless ATTRS_TO_WATCH.any? { |k| changed_attributes.key?(k) } if ATTRS_TO_WATCH.any? { |k| changed_attributes.key?(k) }
new = attributes.select { |k| ATTRS_TO_WATCH.include?(k) }
new = attributes.select { |k| ATTRS_TO_WATCH.include?(k) } old = changed_attributes.select { |k| ATTRS_TO_WATCH.include?(k) }
old = changed_attributes.select { |k| ATTRS_TO_WATCH.include?(k) } meta = new.merge(old) # we are prioritizing the old values, keeping them
meta = new.merge(old) # we are prioritizing the old values, keeping them meta['changed'] = changed_attributes.keys.select { |k| ATTRS_TO_WATCH.include?(k) }
meta['changed'] = changed_attributes.keys.select { |k| ATTRS_TO_WATCH.include?(k) } Events::SynapseUpdated.publish!(self, updated_by, meta)
Events::SynapseUpdated.publish!(self, updated_by, meta) maps.each do |map|
maps.each do |map| ActionCable.server.broadcast 'map_' + map.id.to_s, type: 'synapseUpdated', id: id
ActionCable.server.broadcast 'map_' + map.id.to_s, type: 'synapseUpdated', id: id end
end end
end end
def before_destroyed def before_destroyed
# hard to know how to do this yet, because the synapse actually gets destroyed # hard to know how to do this yet, because the synapse actually gets destroyed
# NotificationService.notify_followers(topic1, 'topic_disconnected', self) #NotificationService.notify_followers(topic1, 'topic_disconnected', self)
# NotificationService.notify_followers(topic2, 'topic_disconnected', self) #NotificationService.notify_followers(topic2, 'topic_disconnected', self)
end end
end end

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
class Token < ApplicationRecord class Token < ApplicationRecord
belongs_to :user belongs_to :user

View file

@ -1,7 +1,6 @@
# frozen_string_literal: true # frozen_string_literal: true
class Topic < ApplicationRecord class Topic < ApplicationRecord
ATTRS_TO_WATCH = %w[name desc link metacode_id permission defer_to_map_id].freeze ATTRS_TO_WATCH = %w(name desc link metacode_id permission defer_to_map_id).freeze
include TopicsHelper include TopicsHelper
include Attachable include Attachable
@ -17,7 +16,7 @@ class Topic < ApplicationRecord
has_many :mappings, as: :mappable, dependent: :destroy has_many :mappings, as: :mappable, dependent: :destroy
has_many :maps, through: :mappings has_many :maps, through: :mappings
has_many :follows, as: :followed, dependent: :destroy has_many :follows, as: :followed, dependent: :destroy
has_many :followers, through: :follows, source: :user has_many :followers, :through => :follows, source: :user
belongs_to :metacode belongs_to :metacode
@ -26,7 +25,7 @@ class Topic < ApplicationRecord
after_create :after_created_async after_create :after_created_async
after_update :after_updated after_update :after_updated
after_update :after_updated_async after_update :after_updated_async
# before_destroy :before_destroyed #before_destroy :before_destroyed
validates :permission, presence: true validates :permission, presence: true
validates :permission, inclusion: { in: Perm::ISSIONS.map(&:to_s) } validates :permission, inclusion: { in: Perm::ISSIONS.map(&:to_s) }
@ -39,13 +38,13 @@ class Topic < ApplicationRecord
topics1.or(topics2) topics1.or(topics2)
end end
scope :relatives, (lambda do |topic_id = nil, user = nil| scope :relatives, ->(topic_id = nil, user = nil) {
# should only see topics through *visible* synapses # should only see topics through *visible* synapses
# e.g. Topic A (commons) -> synapse (private) -> Topic B (commons) must be filtered out # e.g. Topic A (commons) -> synapse (private) -> Topic B (commons) must be filtered out
topic_ids = Pundit.policy_scope(user, Synapse.where(topic1_id: topic_id)).pluck(:topic2_id) topic_ids = Pundit.policy_scope(user, Synapse.where(topic1_id: topic_id)).pluck(:topic2_id)
topic_ids += Pundit.policy_scope(user, Synapse.where(topic2_id: topic_id)).pluck(:topic1_id) topic_ids += Pundit.policy_scope(user, Synapse.where(topic2_id: topic_id)).pluck(:topic1_id)
where(id: topic_ids.uniq) where(id: topic_ids.uniq)
end) }
delegate :name, to: :user, prefix: true delegate :name, to: :user, prefix: true
@ -65,13 +64,13 @@ class Topic < ApplicationRecord
Pundit.policy_scope(user, maps).map(&:name) Pundit.policy_scope(user, maps).map(&:name)
end end
def inmaps_links(user) def inmapsLinks(user)
Pundit.policy_scope(user, maps).map(&:id) Pundit.policy_scope(user, maps).map(&:id)
end end
def as_json(options = {}) def as_json(options = {})
super(methods: %i[user_name user_image collaborator_ids]) super(methods: [:user_name, :user_image, :collaborator_ids])
.merge(inmaps: inmaps(options[:user]), inmapsLinks: inmaps_links(options[:user]), .merge(inmaps: inmaps(options[:user]), inmapsLinks: inmapsLinks(options[:user]),
map_count: map_count(options[:user]), synapse_count: synapse_count(options[:user])) map_count: map_count(options[:user]), synapse_count: synapse_count(options[:user]))
end end
@ -90,7 +89,7 @@ class Topic < ApplicationRecord
def collaborator_ids def collaborator_ids
if defer_to_map if defer_to_map
defer_to_map.editors.reject { |mapper| mapper == user }.map(&:id) defer_to_map.editors.select { |mapper| mapper != user }.map(&:id)
else else
[] []
end end
@ -127,9 +126,14 @@ class Topic < ApplicationRecord
end end
end end
end end
return output if output_format == 'array' if output_format == 'array'
return output.join('; ') if output_format == 'text' return output
raise 'invalid argument to synapses_csv' elsif output_format == 'text'
return output.join('; ')
else
raise 'invalid argument to synapses_csv'
end
output
end end
def topic_autocomplete_method def topic_autocomplete_method
@ -139,7 +143,7 @@ class Topic < ApplicationRecord
protected protected
def set_perm_by_defer def set_perm_by_defer
self.permission = defer_to_map.permission if defer_to_map permission = defer_to_map.permission if defer_to_map
end end
def create_metamap? def create_metamap?
@ -152,33 +156,33 @@ class Topic < ApplicationRecord
end end
def after_created_async def after_created_async
FollowService.follow(self, user, 'created') FollowService.follow(self, self.user, 'created')
# notify users following the topic creator # notify users following the topic creator
end end
handle_asynchronously :after_created_async handle_asynchronously :after_created_async
def after_updated def after_updated
return unless ATTRS_TO_WATCH.any? { |k| changed_attributes.key?(k) } if ATTRS_TO_WATCH.any? { |k| changed_attributes.key?(k) }
new = attributes.select { |k| ATTRS_TO_WATCH.include?(k) }
new = attributes.select { |k| ATTRS_TO_WATCH.include?(k) } old = changed_attributes.select { |k| ATTRS_TO_WATCH.include?(k) }
old = changed_attributes.select { |k| ATTRS_TO_WATCH.include?(k) } meta = new.merge(old) # we are prioritizing the old values, keeping them
meta = new.merge(old) # we are prioritizing the old values, keeping them meta['changed'] = changed_attributes.keys.select { |k| ATTRS_TO_WATCH.include?(k) }
meta['changed'] = changed_attributes.keys.select { |k| ATTRS_TO_WATCH.include?(k) } Events::TopicUpdated.publish!(self, updated_by, meta)
Events::TopicUpdated.publish!(self, updated_by, meta) maps.each do |map|
maps.each do |map| ActionCable.server.broadcast 'map_' + map.id.to_s, type: 'topicUpdated', id: id
ActionCable.server.broadcast 'map_' + map.id.to_s, type: 'topicUpdated', id: id end
end end
end end
def after_updated_async def after_updated_async
return unless ATTRS_TO_WATCH.any? { |k| changed_attributes.key?(k) } if ATTRS_TO_WATCH.any? { |k| changed_attributes.key?(k) }
FollowService.follow(self, updated_by, 'contributed')
FollowService.follow(self, updated_by, 'contributed') end
end end
handle_asynchronously :after_updated_async handle_asynchronously :after_updated_async
def before_destroyed def before_destroyed
# hard to know how to do this yet, because the topic actually gets destroyed # hard to know how to do this yet, because the topic actually gets destroyed
# NotificationService.notify_followers(self, 'topic_deleted', ?) #NotificationService.notify_followers(self, 'topic_deleted', ?)
end end
end end

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
require 'open-uri' require 'open-uri'
class User < ApplicationRecord class User < ApplicationRecord
@ -52,24 +51,26 @@ class User < ApplicationRecord
validates_attachment_content_type :image, content_type: %r{\Aimage/.*\Z} validates_attachment_content_type :image, content_type: %r{\Aimage/.*\Z}
# override default as_json # override default as_json
def as_json(options = {}) def as_json(_options = {})
json = { id: id, json = { id: id,
name: name, name: name,
image: image.url(:sixtyfour), image: image.url(:sixtyfour),
admin: admin } admin: admin }
if options[:follows] if (_options[:follows])
json['follows'] = { json['follows'] = {
topics: following.active.where(followed_type: 'Topic').to_a.map(&:followed_id), topics: following.where(followed_type: 'Topic').to_a.map(&:followed_id),
maps: following.active.where(followed_type: 'Map').to_a.map(&:followed_id) maps: following.where(followed_type: 'Map').to_a.map(&:followed_id)
} }
end end
if options[:follow_settings] if (_options[:follow_settings])
json['follow_topic_on_created'] = settings.follow_topic_on_created == '1' json['follow_topic_on_created'] = settings.follow_topic_on_created == "1"
json['follow_topic_on_contributed'] = settings.follow_topic_on_contributed == '1' json['follow_topic_on_contributed'] = settings.follow_topic_on_contributed == "1"
json['follow_map_on_created'] = settings.follow_map_on_created == '1' json['follow_map_on_created'] = settings.follow_map_on_created == "1"
json['follow_map_on_contributed'] = settings.follow_map_on_contributed == '1' json['follow_map_on_contributed'] = settings.follow_map_on_contributed == "1"
end
if (_options[:email])
json['email'] = email
end end
json['email'] = email if options[:email]
json json
end end
@ -106,14 +107,10 @@ class User < ApplicationRecord
end end
def most_used_metacodes def most_used_metacodes
metacode_counts = topics.to_a.each_with_object(Hash.new(0)) do |topic, list_so_far| topics.to_a.each_with_object(Hash.new(0)) do |topic, memo|
list_so_far[topic.metacode_id] += 1 memo[topic.metacode_id] += 1
list_so_far memo
end end.to_a.sort { |a, b| b[1] <=> a[1] }.map { |i| i[0] }.slice(0, 5)
id_count_pairs = metacode_counts.to_a
id_count_pairs.sort! { |a, b| b[1] <=> a[1] }
metacode_ids = id_count_pairs.map { |i| i[0] }
metacode_ids.slice(0, 5)
end end
# generate a random 8 letter/digit code that they can use to invite people # generate a random 8 letter/digit code that they can use to invite people
@ -136,20 +133,20 @@ class User < ApplicationRecord
end end
def has_map_open(map) def has_map_open(map)
latest_event = Event.where(map: map, user: self) latestEvent = Event.where(map: map, user: self)
.where(kind: %w[user_present_on_map user_not_present_on_map]) .where(kind: ['user_present_on_map', 'user_not_present_on_map'])
.order(:created_at) .order(:created_at)
.last .last
latest_event && latest_event.kind == 'user_present_on_map' latestEvent && latestEvent.kind == 'user_present_on_map'
end end
def has_map_with_synapse_open(synapse) def has_map_with_synapse_open(synapse)
synapse.maps.any? { |map| has_map_open(map) } synapse.maps.any?{|map| has_map_open(map)}
end end
def settings def settings
self[:settings] = UserPreference.new if self[:settings].nil? self[:settings] = UserPreference.new if self[:settings].nil?
unless self[:settings].respond_to?(:follow_topic_on_created) if not self[:settings].respond_to?(:follow_topic_on_created)
self[:settings].initialize_follow_settings self[:settings].initialize_follow_settings
end end
self[:settings] self[:settings]

View file

@ -1,5 +1,4 @@
# frozen_string_literal: true # frozen_string_literal: true
class UserMap < ApplicationRecord class UserMap < ApplicationRecord
belongs_to :map belongs_to :map
belongs_to :user belongs_to :user
@ -19,7 +18,7 @@ class UserMap < ApplicationRecord
def after_created_async def after_created_async
FollowService.follow(map, user, 'shared_on') FollowService.follow(map, user, 'shared_on')
if access_request if access_request
NotificationService.access_approved(access_request) NotificationService.access_approved(self.access_request)
else else
NotificationService.invite_to_edit(self) NotificationService.invite_to_edit(self)
end end

Some files were not shown because too many files have changed in this diff Show more