Compare commits
1 commit
develop
...
feature/br
Author | SHA1 | Date | |
---|---|---|---|
|
619673a2d7 |
335 changed files with 2089 additions and 3754 deletions
4
.github/ISSUE_TEMPLATE.md
vendored
Normal file
4
.github/ISSUE_TEMPLATE.md
vendored
Normal file
|
@ -0,0 +1,4 @@
|
|||
|
||||
|
||||
============
|
||||
100BD/C = (100)(__)(__)/(__)=__
|
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -15,7 +15,6 @@ app/assets/javascripts/webpacked
|
|||
|
||||
#secrets and config
|
||||
.env
|
||||
*.swp
|
||||
|
||||
# Ignore bundler config
|
||||
.bundle
|
||||
|
|
|
@ -12,7 +12,7 @@ Rails:
|
|||
Enabled: true
|
||||
|
||||
Metrics/LineLength:
|
||||
Max: 120
|
||||
Max: 100
|
||||
|
||||
Metrics/AbcSize:
|
||||
Max: 16
|
||||
|
@ -22,8 +22,3 @@ Style/Documentation:
|
|||
|
||||
Style/EmptyMethod:
|
||||
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
13
Gemfile
|
@ -1,12 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
source 'https://rubygems.org'
|
||||
ruby '2.3.0'
|
||||
|
||||
gem 'rails', '~> 5.0.0'
|
||||
|
||||
gem 'active_model_serializers'
|
||||
gem 'aws-sdk', '~> 2.7.0'
|
||||
gem 'aws-sdk'
|
||||
gem 'best_in_place'
|
||||
gem 'delayed_job'
|
||||
gem 'delayed_job_active_record'
|
||||
|
@ -25,7 +24,7 @@ gem 'pundit'
|
|||
gem 'pundit_extra'
|
||||
gem 'rack-attack'
|
||||
gem 'rack-cors'
|
||||
gem 'redis', '~> 3.3.3'
|
||||
gem 'redis'
|
||||
gem 'slack-notifier'
|
||||
gem 'snorlax'
|
||||
gem 'sucker_punch'
|
||||
|
@ -38,7 +37,7 @@ gem 'uglifier'
|
|||
|
||||
group :test do
|
||||
gem 'brakeman', require: false
|
||||
gem 'factory_bot_rails'
|
||||
gem 'factory_girl_rails'
|
||||
gem 'json-schema'
|
||||
gem 'rspec-rails'
|
||||
gem 'shoulda-matchers'
|
||||
|
@ -48,10 +47,10 @@ end
|
|||
group :development, :test do
|
||||
gem 'better_errors'
|
||||
gem 'binding_of_caller'
|
||||
gem 'faker'
|
||||
gem 'pry-byebug'
|
||||
gem 'pry-rails'
|
||||
gem 'rubocop', '~> 0.48.1' # match code climate https://github.com/tootsuite/mastodon/issues/1758
|
||||
gem 'timecop'
|
||||
gem 'rubocop'
|
||||
gem 'tunemygc'
|
||||
gem 'faker'
|
||||
gem 'timecop'
|
||||
end
|
||||
|
|
290
Gemfile.lock
290
Gemfile.lock
|
@ -1,50 +1,50 @@
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
actioncable (5.0.5)
|
||||
actionpack (= 5.0.5)
|
||||
nio4r (>= 1.2, < 3.0)
|
||||
actioncable (5.0.1)
|
||||
actionpack (= 5.0.1)
|
||||
nio4r (~> 1.2)
|
||||
websocket-driver (~> 0.6.1)
|
||||
actionmailer (5.0.5)
|
||||
actionpack (= 5.0.5)
|
||||
actionview (= 5.0.5)
|
||||
activejob (= 5.0.5)
|
||||
actionmailer (5.0.1)
|
||||
actionpack (= 5.0.1)
|
||||
actionview (= 5.0.1)
|
||||
activejob (= 5.0.1)
|
||||
mail (~> 2.5, >= 2.5.4)
|
||||
rails-dom-testing (~> 2.0)
|
||||
actionpack (5.0.5)
|
||||
actionview (= 5.0.5)
|
||||
activesupport (= 5.0.5)
|
||||
actionpack (5.0.1)
|
||||
actionview (= 5.0.1)
|
||||
activesupport (= 5.0.1)
|
||||
rack (~> 2.0)
|
||||
rack-test (~> 0.6.3)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||
actionview (5.0.5)
|
||||
activesupport (= 5.0.5)
|
||||
actionview (5.0.1)
|
||||
activesupport (= 5.0.1)
|
||||
builder (~> 3.1)
|
||||
erubis (~> 2.7.0)
|
||||
rails-dom-testing (~> 2.0)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
||||
active_model_serializers (0.10.6)
|
||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||
active_model_serializers (0.10.4)
|
||||
actionpack (>= 4.1, < 6)
|
||||
activemodel (>= 4.1, < 6)
|
||||
case_transform (>= 0.2)
|
||||
jsonapi-renderer (>= 0.1.1.beta1, < 0.2)
|
||||
activejob (5.0.5)
|
||||
activesupport (= 5.0.5)
|
||||
jsonapi (= 0.1.1.beta6)
|
||||
activejob (5.0.1)
|
||||
activesupport (= 5.0.1)
|
||||
globalid (>= 0.3.6)
|
||||
activemodel (5.0.5)
|
||||
activesupport (= 5.0.5)
|
||||
activerecord (5.0.5)
|
||||
activemodel (= 5.0.5)
|
||||
activesupport (= 5.0.5)
|
||||
activemodel (5.0.1)
|
||||
activesupport (= 5.0.1)
|
||||
activerecord (5.0.1)
|
||||
activemodel (= 5.0.1)
|
||||
activesupport (= 5.0.1)
|
||||
arel (~> 7.0)
|
||||
activesupport (5.0.5)
|
||||
activesupport (5.0.1)
|
||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||
i18n (~> 0.7)
|
||||
minitest (~> 5.1)
|
||||
tzinfo (~> 1.1)
|
||||
addressable (2.5.2)
|
||||
public_suffix (>= 2.0.2, < 4.0)
|
||||
addressable (2.5.0)
|
||||
public_suffix (~> 2.0, >= 2.0.2)
|
||||
arel (7.1.4)
|
||||
ast (2.3.0)
|
||||
aws-sdk (2.7.0)
|
||||
|
@ -54,82 +54,83 @@ GEM
|
|||
jmespath (~> 1.0)
|
||||
aws-sdk-resources (2.7.0)
|
||||
aws-sdk-core (= 2.7.0)
|
||||
aws-sigv4 (1.0.2)
|
||||
aws-sigv4 (1.0.0)
|
||||
bcrypt (3.1.11)
|
||||
best_in_place (3.1.1)
|
||||
best_in_place (3.1.0)
|
||||
actionpack (>= 3.2)
|
||||
railties (>= 3.2)
|
||||
better_errors (2.3.0)
|
||||
better_errors (2.1.1)
|
||||
coderay (>= 1.0.0)
|
||||
erubi (>= 1.0.0)
|
||||
erubis (>= 2.6.6)
|
||||
rack (>= 0.9.0)
|
||||
binding_of_caller (0.7.2)
|
||||
debug_inspector (>= 0.0.1)
|
||||
brakeman (3.7.2)
|
||||
brakeman (3.4.1)
|
||||
builder (3.2.3)
|
||||
byebug (9.1.0)
|
||||
carrierwave (1.1.0)
|
||||
byebug (9.0.6)
|
||||
carrierwave (1.0.0)
|
||||
activemodel (>= 4.0.0)
|
||||
activesupport (>= 4.0.0)
|
||||
mime-types (>= 1.16)
|
||||
case_transform (0.2)
|
||||
activesupport
|
||||
climate_control (0.2.0)
|
||||
climate_control (0.1.0)
|
||||
cocaine (0.5.8)
|
||||
climate_control (>= 0.0.3, < 1.0)
|
||||
coderay (1.1.2)
|
||||
concurrent-ruby (1.0.5)
|
||||
debug_inspector (0.0.3)
|
||||
delayed_job (4.1.3)
|
||||
activesupport (>= 3.0, < 5.2)
|
||||
delayed_job_active_record (4.1.2)
|
||||
activerecord (>= 3.0, < 5.2)
|
||||
coderay (1.1.1)
|
||||
concurrent-ruby (1.0.4)
|
||||
debug_inspector (0.0.2)
|
||||
delayed_job (4.1.2)
|
||||
activesupport (>= 3.0, < 5.1)
|
||||
delayed_job_active_record (4.1.1)
|
||||
activerecord (>= 3.0, < 5.1)
|
||||
delayed_job (>= 3.0, < 5)
|
||||
devise (4.3.0)
|
||||
devise (4.2.0)
|
||||
bcrypt (~> 3.0)
|
||||
orm_adapter (~> 0.1)
|
||||
railties (>= 4.1.0, < 5.2)
|
||||
railties (>= 4.1.0, < 5.1)
|
||||
responders
|
||||
warden (~> 1.2.3)
|
||||
diff-lcs (1.3)
|
||||
docile (1.1.5)
|
||||
doorkeeper (4.2.6)
|
||||
doorkeeper (4.2.0)
|
||||
railties (>= 4.2)
|
||||
dotenv (2.2.1)
|
||||
dotenv-rails (2.2.1)
|
||||
dotenv (= 2.2.1)
|
||||
railties (>= 3.2, < 5.2)
|
||||
erubi (1.6.1)
|
||||
dotenv (2.1.2)
|
||||
dotenv-rails (2.1.2)
|
||||
dotenv (= 2.1.2)
|
||||
railties (>= 3.2, < 5.1)
|
||||
erubis (2.7.0)
|
||||
exception_notification (4.2.2)
|
||||
exception_notification (4.2.1)
|
||||
actionmailer (>= 4.0, < 6)
|
||||
activesupport (>= 4.0, < 6)
|
||||
execjs (2.7.0)
|
||||
factory_bot (4.8.2)
|
||||
factory_girl (4.8.0)
|
||||
activesupport (>= 3.0.0)
|
||||
factory_bot_rails (4.8.2)
|
||||
factory_bot (~> 4.8.2)
|
||||
factory_girl_rails (4.8.0)
|
||||
factory_girl (~> 4.8.0)
|
||||
railties (>= 3.0.0)
|
||||
faker (1.8.4)
|
||||
faker (1.7.3)
|
||||
i18n (~> 0.5)
|
||||
ffi (1.9.18)
|
||||
globalid (0.4.0)
|
||||
activesupport (>= 4.2.0)
|
||||
httparty (0.15.6)
|
||||
globalid (0.3.7)
|
||||
activesupport (>= 4.1.0)
|
||||
httparty (0.14.0)
|
||||
multi_xml (>= 0.5.2)
|
||||
i18n (0.9.3)
|
||||
concurrent-ruby (~> 1.0)
|
||||
i18n (0.7.0)
|
||||
jmespath (1.3.1)
|
||||
jquery-rails (4.3.1)
|
||||
jquery-rails (4.2.2)
|
||||
rails-dom-testing (>= 1, < 3)
|
||||
railties (>= 4.2.0)
|
||||
thor (>= 0.14, < 2.0)
|
||||
jquery-ui-rails (6.0.1)
|
||||
railties (>= 3.2.16)
|
||||
json (2.1.0)
|
||||
json-schema (2.8.0)
|
||||
json (2.0.3)
|
||||
json-schema (2.7.0)
|
||||
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)
|
||||
activesupport (>= 4.1.0)
|
||||
kaminari-actionview (= 1.0.1)
|
||||
|
@ -144,154 +145,145 @@ GEM
|
|||
kaminari-core (1.0.1)
|
||||
loofah (2.0.3)
|
||||
nokogiri (>= 1.5.9)
|
||||
mail (2.6.6)
|
||||
mail (2.6.4)
|
||||
mime-types (>= 1.16, < 4)
|
||||
mailboxer (0.15.1)
|
||||
mailboxer (0.14.0)
|
||||
carrierwave (>= 0.5.8)
|
||||
rails (>= 5.0.0)
|
||||
rails (>= 4.2.0)
|
||||
method_source (0.8.2)
|
||||
mime-types (3.1)
|
||||
mime-types-data (~> 3.2015)
|
||||
mime-types-data (3.2016.0521)
|
||||
mimemagic (0.3.2)
|
||||
mini_portile2 (2.3.0)
|
||||
minitest (5.11.1)
|
||||
mini_portile2 (2.1.0)
|
||||
minitest (5.10.1)
|
||||
multi_xml (0.6.0)
|
||||
nio4r (2.1.0)
|
||||
nokogiri (1.8.1)
|
||||
mini_portile2 (~> 2.3.0)
|
||||
nio4r (1.2.1)
|
||||
nokogiri (1.7.0.1)
|
||||
mini_portile2 (~> 2.1.0)
|
||||
orm_adapter (0.5.0)
|
||||
paperclip (5.2.0)
|
||||
paperclip (5.1.0)
|
||||
activemodel (>= 4.2.0)
|
||||
activesupport (>= 4.2.0)
|
||||
cocaine (~> 0.5.5)
|
||||
mime-types
|
||||
mimemagic (~> 0.3.0)
|
||||
parser (2.4.0.2)
|
||||
ast (~> 2.3)
|
||||
pg (0.21.0)
|
||||
parser (2.3.3.1)
|
||||
ast (~> 2.2)
|
||||
pg (0.19.0)
|
||||
powerpack (0.1.1)
|
||||
pry (0.10.4)
|
||||
coderay (~> 1.1.0)
|
||||
method_source (~> 0.8.1)
|
||||
slop (~> 3.4)
|
||||
pry-byebug (3.5.0)
|
||||
byebug (~> 9.1)
|
||||
pry-byebug (3.4.2)
|
||||
byebug (~> 9.0)
|
||||
pry (~> 0.10)
|
||||
pry-rails (0.3.6)
|
||||
pry (>= 0.10.4)
|
||||
public_suffix (3.0.0)
|
||||
puma (3.10.0)
|
||||
pry-rails (0.3.4)
|
||||
pry (>= 0.9.10)
|
||||
public_suffix (2.0.5)
|
||||
puma (3.6.2)
|
||||
pundit (1.1.0)
|
||||
activesupport (>= 3.0.0)
|
||||
pundit_extra (0.3.0)
|
||||
rack (2.0.3)
|
||||
rack (2.0.1)
|
||||
rack-attack (5.0.1)
|
||||
rack
|
||||
rack-cors (1.0.1)
|
||||
rack-cors (0.4.0)
|
||||
rack-test (0.6.3)
|
||||
rack (>= 1.0)
|
||||
rails (5.0.5)
|
||||
actioncable (= 5.0.5)
|
||||
actionmailer (= 5.0.5)
|
||||
actionpack (= 5.0.5)
|
||||
actionview (= 5.0.5)
|
||||
activejob (= 5.0.5)
|
||||
activemodel (= 5.0.5)
|
||||
activerecord (= 5.0.5)
|
||||
activesupport (= 5.0.5)
|
||||
bundler (>= 1.3.0)
|
||||
railties (= 5.0.5)
|
||||
rails (5.0.1)
|
||||
actioncable (= 5.0.1)
|
||||
actionmailer (= 5.0.1)
|
||||
actionpack (= 5.0.1)
|
||||
actionview (= 5.0.1)
|
||||
activejob (= 5.0.1)
|
||||
activemodel (= 5.0.1)
|
||||
activerecord (= 5.0.1)
|
||||
activesupport (= 5.0.1)
|
||||
bundler (>= 1.3.0, < 2.0)
|
||||
railties (= 5.0.1)
|
||||
sprockets-rails (>= 2.0.0)
|
||||
rails-dom-testing (2.0.3)
|
||||
activesupport (>= 4.2.0)
|
||||
nokogiri (>= 1.6)
|
||||
rails-dom-testing (2.0.2)
|
||||
activesupport (>= 4.2.0, < 6.0)
|
||||
nokogiri (~> 1.6)
|
||||
rails-html-sanitizer (1.0.3)
|
||||
loofah (~> 2.0)
|
||||
railties (5.0.5)
|
||||
actionpack (= 5.0.5)
|
||||
activesupport (= 5.0.5)
|
||||
railties (5.0.1)
|
||||
actionpack (= 5.0.1)
|
||||
activesupport (= 5.0.1)
|
||||
method_source
|
||||
rake (>= 0.8.7)
|
||||
thor (>= 0.18.1, < 2.0)
|
||||
rainbow (2.2.2)
|
||||
rake
|
||||
rake (12.3.0)
|
||||
rb-fsevent (0.10.2)
|
||||
rb-inotify (0.9.10)
|
||||
ffi (>= 0.5.0, < 2)
|
||||
redis (3.3.3)
|
||||
responders (2.4.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)
|
||||
rainbow (2.2.1)
|
||||
rake (12.0.0)
|
||||
redis (3.3.2)
|
||||
responders (2.3.0)
|
||||
railties (>= 4.2.0, < 5.1)
|
||||
rspec-core (3.5.4)
|
||||
rspec-support (~> 3.5.0)
|
||||
rspec-expectations (3.5.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.6.0)
|
||||
rspec-mocks (3.6.0)
|
||||
rspec-support (~> 3.5.0)
|
||||
rspec-mocks (3.5.0)
|
||||
diff-lcs (>= 1.2.0, < 2.0)
|
||||
rspec-support (~> 3.6.0)
|
||||
rspec-rails (3.6.1)
|
||||
rspec-support (~> 3.5.0)
|
||||
rspec-rails (3.5.2)
|
||||
actionpack (>= 3.0)
|
||||
activesupport (>= 3.0)
|
||||
railties (>= 3.0)
|
||||
rspec-core (~> 3.6.0)
|
||||
rspec-expectations (~> 3.6.0)
|
||||
rspec-mocks (~> 3.6.0)
|
||||
rspec-support (~> 3.6.0)
|
||||
rspec-support (3.6.0)
|
||||
rubocop (0.48.1)
|
||||
rspec-core (~> 3.5.0)
|
||||
rspec-expectations (~> 3.5.0)
|
||||
rspec-mocks (~> 3.5.0)
|
||||
rspec-support (~> 3.5.0)
|
||||
rspec-support (3.5.0)
|
||||
rubocop (0.47.1)
|
||||
parser (>= 2.3.3.1, < 3.0)
|
||||
powerpack (~> 0.1)
|
||||
rainbow (>= 1.99.1, < 3.0)
|
||||
ruby-progressbar (~> 1.7)
|
||||
unicode-display_width (~> 1.0, >= 1.0.1)
|
||||
ruby-progressbar (1.9.0)
|
||||
sass (3.5.1)
|
||||
sass-listen (~> 4.0.0)
|
||||
sass-listen (4.0.0)
|
||||
rb-fsevent (~> 0.9, >= 0.9.4)
|
||||
rb-inotify (~> 0.9, >= 0.9.7)
|
||||
ruby-progressbar (1.8.1)
|
||||
sass (3.4.23)
|
||||
sass-rails (5.0.6)
|
||||
railties (>= 4.0.0, < 6)
|
||||
sass (~> 3.1)
|
||||
sprockets (>= 2.8, < 4.0)
|
||||
sprockets-rails (>= 2.0, < 4.0)
|
||||
tilt (>= 1.1, < 3)
|
||||
shoulda-matchers (3.1.2)
|
||||
shoulda-matchers (3.1.1)
|
||||
activesupport (>= 4.0.0)
|
||||
simplecov (0.15.0)
|
||||
simplecov (0.12.0)
|
||||
docile (~> 1.1.0)
|
||||
json (>= 1.8, < 3)
|
||||
simplecov-html (~> 0.10.0)
|
||||
simplecov-html (0.10.2)
|
||||
slack-notifier (2.3.1)
|
||||
simplecov-html (0.10.0)
|
||||
slack-notifier (2.0.0)
|
||||
slop (3.6.0)
|
||||
snorlax (0.1.6)
|
||||
rails (> 4.1)
|
||||
sprockets (3.7.1)
|
||||
concurrent-ruby (~> 1.0)
|
||||
rack (> 1, < 3)
|
||||
sprockets-rails (3.2.1)
|
||||
sprockets-rails (3.2.0)
|
||||
actionpack (>= 4.0)
|
||||
activesupport (>= 4.0)
|
||||
sprockets (>= 3.0.0)
|
||||
sucker_punch (2.0.3)
|
||||
sucker_punch (2.0.2)
|
||||
concurrent-ruby (~> 1.0.0)
|
||||
thor (0.20.0)
|
||||
thread_safe (0.3.6)
|
||||
tilt (2.0.8)
|
||||
timecop (0.9.1)
|
||||
thor (0.19.4)
|
||||
thread_safe (0.3.5)
|
||||
tilt (2.0.5)
|
||||
timecop (0.8.1)
|
||||
tunemygc (1.0.69)
|
||||
tzinfo (1.2.4)
|
||||
tzinfo (1.2.2)
|
||||
thread_safe (~> 0.1)
|
||||
uglifier (3.2.0)
|
||||
uglifier (3.0.4)
|
||||
execjs (>= 0.3.0, < 3)
|
||||
unicode-display_width (1.3.0)
|
||||
warden (1.2.7)
|
||||
unicode-display_width (1.1.3)
|
||||
warden (1.2.6)
|
||||
rack (>= 1.0)
|
||||
websocket-driver (0.6.5)
|
||||
websocket-driver (0.6.4)
|
||||
websocket-extensions (>= 0.1.0)
|
||||
websocket-extensions (0.1.2)
|
||||
|
||||
|
@ -300,7 +292,7 @@ PLATFORMS
|
|||
|
||||
DEPENDENCIES
|
||||
active_model_serializers
|
||||
aws-sdk (~> 2.7.0)
|
||||
aws-sdk
|
||||
best_in_place
|
||||
better_errors
|
||||
binding_of_caller
|
||||
|
@ -311,7 +303,7 @@ DEPENDENCIES
|
|||
doorkeeper
|
||||
dotenv-rails
|
||||
exception_notification
|
||||
factory_bot_rails
|
||||
factory_girl_rails
|
||||
faker
|
||||
httparty
|
||||
jquery-rails
|
||||
|
@ -330,9 +322,9 @@ DEPENDENCIES
|
|||
rack-attack
|
||||
rack-cors
|
||||
rails (~> 5.0.0)
|
||||
redis (~> 3.3.3)
|
||||
redis
|
||||
rspec-rails
|
||||
rubocop (~> 0.48.1)
|
||||
rubocop
|
||||
sass-rails
|
||||
shoulda-matchers
|
||||
simplecov
|
||||
|
@ -347,4 +339,4 @@ RUBY VERSION
|
|||
ruby 2.3.0p0
|
||||
|
||||
BUNDLED WITH
|
||||
1.16.1
|
||||
1.14.6
|
||||
|
|
41
README.md
41
README.md
|
@ -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 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:
|
||||
- [Mac Install Walkthrough][mac-installation]
|
||||
- [Ubuntu Install Walkthrough][ubuntu-installation]
|
||||
To start servers which will run metamaps you can then run:
|
||||
```
|
||||
./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:
|
||||
- [Vagrant installation][vagrant-installation]
|
||||
You can sign in with the default account
|
||||
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
|
||||
- [Outdated Windows Walkthrough][windows-installation]
|
||||
Start mapping and programming!
|
||||
|
||||
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
|
||||
|
||||
|
@ -56,7 +76,4 @@ Copyright (c) 2017 Connor Turland
|
|||
[license]: https://github.com/metamaps/metamaps/blob/develop/LICENSE
|
||||
[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
|
||||
[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
|
||||
|
|
1
Rakefile
Executable file → Normal file
1
Rakefile
Executable file → Normal file
|
@ -1,6 +1,5 @@
|
|||
#!/usr/bin/env rake
|
||||
# frozen_string_literal: true
|
||||
|
||||
# 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.
|
||||
|
||||
|
|
2
Vagrantfile
vendored
2
Vagrantfile
vendored
|
@ -37,7 +37,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
|||
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.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.synced_folder '.', '/vagrant', nfs: true
|
||||
|
||||
|
|
BIN
app/assets/images/arrowperms_sprite.png
Normal file
BIN
app/assets/images/arrowperms_sprite.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 543 B |
|
@ -4,11 +4,11 @@ $(document).ready(function() {
|
|||
if (window.location.pathname === '/') {
|
||||
$.ajax({
|
||||
type: 'GET',
|
||||
url: 'https://i.vimeocdn.com/video/',
|
||||
url: 'https://player.vimeo.com',
|
||||
error: function(e) {
|
||||
$('.homeVideo').hide()
|
||||
$('.homeVideo').replaceWith($('<video/>', {
|
||||
poster: '<%= asset_path('metamaps-intro-poster.webp') %>',
|
||||
poster: '/assets/metamaps-intro-poster.webp',
|
||||
width: '560',
|
||||
height: '315',
|
||||
class: 'homeVideo',
|
|
@ -56,15 +56,16 @@
|
|||
}
|
||||
|
||||
li.toggledOff {
|
||||
opacity: 0.6;
|
||||
opacity: 0.4;
|
||||
}
|
||||
}
|
||||
|
||||
.centerContent {
|
||||
.blackBox {
|
||||
width: 760px;
|
||||
margin: 0 auto;
|
||||
padding: 80px 0 60px 20px;
|
||||
background: rgba(125, 125, 125, 0.4);
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
color: white;
|
||||
overflow: hidden;
|
||||
position: relative;
|
||||
|
||||
|
@ -84,10 +85,10 @@
|
|||
display: table-row;
|
||||
}
|
||||
tr:nth-child(odd) {
|
||||
background: rgba(125, 125, 125, 0.2);
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
}
|
||||
tr:nth-child(even) {
|
||||
background: rgba(125, 125, 125, 0.3);
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
th,
|
||||
td {
|
||||
|
|
|
@ -826,7 +826,6 @@ label {
|
|||
font-size: 14px;
|
||||
line-height: 14px;
|
||||
color: #757575;
|
||||
cursor: pointer;
|
||||
}
|
||||
.accountListItem:hover {
|
||||
color: #424242;
|
||||
|
@ -1915,10 +1914,14 @@ input.collaboratorSearchField {
|
|||
background-position: -32px 0;
|
||||
}
|
||||
.yourMap .mapPermission:hover {
|
||||
background-image: url(<%= asset_data_uri('arrowperms_sprite.png') %>);
|
||||
cursor: pointer;
|
||||
background-position: -32px 0;
|
||||
}
|
||||
.yourMap .mapPermission.minimize {
|
||||
background-image: url(<%= asset_data_uri('arrowperms_sprite.png') %>) !important;
|
||||
cursor: pointer;
|
||||
background-position: 0 0;
|
||||
}
|
||||
.mapInfoBox .mapPermission .permissionSelect {
|
||||
list-style: none;
|
||||
|
@ -2930,6 +2933,136 @@ and it won't be important on password protected instances */
|
|||
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 */
|
||||
|
||||
.requestInvite {
|
||||
|
@ -3017,15 +3150,11 @@ script.data-gratipay-username {
|
|||
}
|
||||
|
||||
.topicFollow {
|
||||
height: 24px;
|
||||
line-height: 24px;
|
||||
text-align: center;
|
||||
height: 48px;
|
||||
line-height: 48px;
|
||||
border-top: 1px solid #BDBDBD;
|
||||
background: #FFF;
|
||||
cursor: pointer;
|
||||
font-family: helvetica, sans-serif;
|
||||
float: left;
|
||||
width: 72px;
|
||||
text-align: right;
|
||||
padding: 12px 0;
|
||||
color: #4fb5c0;
|
||||
font-size: 13px;
|
||||
font-weight: bold;
|
||||
font-family: din-regular;
|
||||
}
|
||||
|
|
|
@ -1,12 +1,9 @@
|
|||
$mid-gray: #8A8A8A;
|
||||
$mid-gray-opacity: rgba(66, 66, 66, 0.6);
|
||||
|
||||
.nameCounter {
|
||||
position: absolute;
|
||||
bottom: 1px;
|
||||
right: 2px;
|
||||
font-size: 11px;
|
||||
font-family: helvetica, sans-serif;
|
||||
font-family: helvetica;
|
||||
color: #727272;
|
||||
line-height: 11px;
|
||||
display: none;
|
||||
|
@ -45,7 +42,7 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
|
|||
z-index:2;
|
||||
color: #424242;
|
||||
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 {
|
||||
|
@ -67,6 +64,7 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
|
|||
display:block;
|
||||
position:relative;
|
||||
width:100%;
|
||||
min-height:360px;
|
||||
z-index: 25;
|
||||
}
|
||||
.CardOnGraph.hasAttachment {
|
||||
|
@ -75,10 +73,11 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
|
|||
|
||||
.CardOnGraph .title {
|
||||
word-break: break-word;
|
||||
font-size: 20px;
|
||||
line-height: 24px;
|
||||
font-size: 18px;
|
||||
line-height: 22px;
|
||||
display: table;
|
||||
padding: 20px 0;
|
||||
padding: 8px 0 16px;
|
||||
height: 80px;
|
||||
text-align: center;
|
||||
font-family: 'din-regular', sans-serif;
|
||||
width: 300px;
|
||||
|
@ -89,6 +88,11 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
|
|||
display: table-cell;
|
||||
vertical-align: middle;
|
||||
padding: 0 16px;
|
||||
|
||||
&.riek-editing {
|
||||
position: absolute;
|
||||
top: 32px;
|
||||
}
|
||||
}
|
||||
.canEdit #titleActivator:hover {
|
||||
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 {
|
||||
font-family: 'din-regular', sans-serif;
|
||||
color: #424242;
|
||||
font-size: 20px;
|
||||
line-height: 24px;
|
||||
font-size: 18px;
|
||||
line-height: 22px;
|
||||
height: 3em;
|
||||
padding: 5px 0;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
|
@ -115,23 +120,11 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
|
|||
.CardOnGraph .scroll {
|
||||
display:block;
|
||||
padding: 8px 0 8px 16px;
|
||||
height: 152px;
|
||||
font-size: 13px;
|
||||
line-height:15px;
|
||||
font-family: helvetica, sans-serif;
|
||||
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 {
|
||||
height: auto;
|
||||
|
@ -143,12 +136,14 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
|
|||
font-family: helvetica, sans-serif;
|
||||
color: #424242;
|
||||
padding: 0;
|
||||
width: 258px;
|
||||
width: 100%;
|
||||
margin: 0;
|
||||
border: 0;
|
||||
outline: none;
|
||||
font-size: 12px;
|
||||
line-height: 15px;
|
||||
background: none;
|
||||
overflow-y: scroll;
|
||||
resize: none;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -182,9 +177,12 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
|
|||
|
||||
.CardOnGraph .riek_desc {
|
||||
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-position: top right;
|
||||
background-repeat: no-repeat;
|
||||
|
@ -197,7 +195,9 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
|
|||
|
||||
.CardOnGraph .links {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
border-bottom: 1px solid #BDBDBD;
|
||||
border-top: 1px solid #BDBDBD;
|
||||
background-color: #e0e0e0;
|
||||
|
||||
.linkItem {
|
||||
float: left;
|
||||
|
@ -213,52 +213,37 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
|
|||
}
|
||||
|
||||
.icon {
|
||||
position: absolute;
|
||||
z-index: 1;
|
||||
padding: 0;
|
||||
height: 48px;
|
||||
margin-right: 10px;
|
||||
width: 100%;
|
||||
|
||||
.metacodeImage {
|
||||
cursor: move;
|
||||
position: absolute;
|
||||
left: -18px;
|
||||
top: 6px;
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
background-size:36px 36px;
|
||||
position: relative;
|
||||
left: -23px;
|
||||
top: 1px;
|
||||
width: 46px;
|
||||
height: 46px;
|
||||
background-size:46px 46px;
|
||||
background-position:0 0;
|
||||
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 {
|
||||
bottom: 7px;
|
||||
margin-left: 16px;
|
||||
margin-left: 40px;
|
||||
|
||||
.contributorIcon {
|
||||
position: relative;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
border-radius: 16px;
|
||||
margin: 5px 5px 5px 0;
|
||||
top: 11px;
|
||||
margin: 5px;
|
||||
top: 8px;
|
||||
left: 0;
|
||||
border-radius: 16px;
|
||||
}
|
||||
|
||||
span {
|
||||
|
@ -267,34 +252,52 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
|
|||
}
|
||||
|
||||
.contributorName {
|
||||
display: none;
|
||||
position: absolute;
|
||||
background: black;
|
||||
text-align: center;
|
||||
color: white;
|
||||
border-radius: 2px;
|
||||
font-family: din-regular;
|
||||
margin-top: 20px;
|
||||
display: inline-block;
|
||||
vertical-align: middle;
|
||||
width: 97px;
|
||||
padding: 0 8px 0 4px;
|
||||
line-height: 15px;
|
||||
font-size: 12px;
|
||||
padding: 3px 5px 2px;
|
||||
white-space: nowrap;
|
||||
overflow: hidden;
|
||||
text-overflow: ellipsis;
|
||||
margin-top: 8px;
|
||||
|
||||
&: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 {
|
||||
padding:17px 38px 17px 0;
|
||||
width: 22px;
|
||||
text-align: right;
|
||||
padding:17px 0 17px 36px;
|
||||
margin-left: 12px;
|
||||
|
||||
.mapCountIcon {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 0;
|
||||
left: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background-image: url(<%= asset_data_uri('map32_sprite.png') %>);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0 0;
|
||||
cursor: pointer;
|
||||
opacity: 0.6;
|
||||
}
|
||||
|
||||
&:hover .mapCountIcon {
|
||||
|
@ -303,18 +306,18 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
|
|||
|
||||
.tip, .hoverTip {
|
||||
top: 44px;
|
||||
right: 0px;
|
||||
left: 0px;
|
||||
font-size: 12px !important;
|
||||
|
||||
&:before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 26px;
|
||||
right: 10px;
|
||||
left: 10px;
|
||||
margin-top: -30px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-bottom: 4px solid $mid-gray;
|
||||
border-bottom: 4px solid #000000;
|
||||
border-left: 5px solid transparent;
|
||||
border-right: 5px solid transparent;
|
||||
}
|
||||
|
@ -324,9 +327,10 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
|
|||
white-space: nowrap;
|
||||
font-family: 'din-regular';
|
||||
top: 44px;
|
||||
left: 0px;
|
||||
font-size: 12px !important;
|
||||
position: absolute;
|
||||
background: $mid-gray;
|
||||
background: black;
|
||||
color: white;
|
||||
border-radius: 4px;
|
||||
line-height: 17px;
|
||||
|
@ -358,31 +362,28 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
|
|||
}
|
||||
|
||||
.synapseCount {
|
||||
width: 22px;
|
||||
padding:17px 38px 17px 0;
|
||||
text-align: right;
|
||||
margin-right: 4px;
|
||||
margin-left: 26px;
|
||||
width: 24px;
|
||||
padding:17px 0 17px 32px;
|
||||
|
||||
.synapseCountIcon {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
right: 0;
|
||||
left: 0;
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
background-image: url(<%= asset_data_uri('synapse32_sprite.png') %>);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0 0;
|
||||
opacity: 0.6;
|
||||
}
|
||||
hover .synapseCountIcon {
|
||||
background-position: 0 -32px;
|
||||
}
|
||||
.tip {
|
||||
position: absolute;
|
||||
background: $mid-gray;
|
||||
background: black;
|
||||
width: auto;
|
||||
top: 44px;
|
||||
right: 0px;
|
||||
color: white;
|
||||
white-space: nowrap;
|
||||
border-radius: 2px;
|
||||
|
@ -397,10 +398,10 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
|
|||
content: '';
|
||||
position: absolute;
|
||||
margin-top: -8px;
|
||||
right: 12px;
|
||||
margin-left: 6px;
|
||||
width: 0;
|
||||
height: 0;
|
||||
border-bottom: 4px solid $mid-gray;
|
||||
border-bottom: 4px solid black;
|
||||
border-left: 5px solid transparent;
|
||||
border-right: 5px solid transparent;
|
||||
}
|
||||
|
@ -412,10 +413,6 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
|
|||
color: #4FC059;
|
||||
}
|
||||
|
||||
.linkItem.mapPerm {
|
||||
margin-right: 8px;
|
||||
}
|
||||
|
||||
.mapPerm {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
|
@ -437,10 +434,14 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
|
|||
}
|
||||
|
||||
.yourTopic .mapPerm:hover, .yourEdge .mapPerm:hover {
|
||||
background-image: url(<%= asset_data_uri('arrowperms_sprite.png') %>);
|
||||
background-position: -32px 0;
|
||||
cursor:pointer;
|
||||
}
|
||||
.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 {
|
||||
list-style: none;
|
||||
|
@ -476,34 +477,32 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
|
|||
}
|
||||
|
||||
.CardOnGraph .metacodeTitle {
|
||||
font-family: 'din-regular';
|
||||
font-style: italic;
|
||||
font-family: 'vinyl';
|
||||
text-transform: uppercase;
|
||||
position: absolute;
|
||||
line-height: 24px;
|
||||
height: 26px;
|
||||
font-size: 18px;
|
||||
padding: 13px 24px 9px 24px;
|
||||
font-size: 24px;
|
||||
display: none;
|
||||
width: 90%;
|
||||
padding: 13px 0 9px 10%;
|
||||
background-color: #E0E0E0;
|
||||
color: #424242;
|
||||
width: 120px;
|
||||
max-width: 120px;
|
||||
white-space: nowrap;
|
||||
text-overflow: ellipsis;
|
||||
overflow: hidden;
|
||||
}
|
||||
.permission.canEdit .metacodeTitle {
|
||||
cursor:pointer;
|
||||
}
|
||||
|
||||
.permission.canEdit .expandMetacodeSelect {
|
||||
position: relative;
|
||||
top: 2px;
|
||||
left: 4px;
|
||||
position: absolute;
|
||||
top: 16px;
|
||||
right: 16px;
|
||||
width: 16px;
|
||||
height: 16px;
|
||||
background-image: url(<%= asset_data_uri('arrowright_sprite.png') %>);
|
||||
background-repeat: no-repeat;
|
||||
background-position: 0 -32px;
|
||||
display: inline-block;
|
||||
-webkit-transform: rotate(90deg);
|
||||
transform: rotate(90deg);
|
||||
}
|
||||
.permission.canEdit .minimize .expandMetacodeSelect {
|
||||
|
||||
|
@ -520,8 +519,8 @@ $mid-gray-opacity: rgba(66, 66, 66, 0.6);
|
|||
background: #EAEAEA;
|
||||
white-space: nowrap;
|
||||
position: absolute;
|
||||
top: 48px;
|
||||
box-shadow: 2px 2px 2px rgba(125, 125, 125, 0.23), -2px -1px 3px rgba(125, 125, 125, 0.16);
|
||||
left: 300px;
|
||||
top: -1px;
|
||||
}
|
||||
.CardOnGraph .metacodeSelect ul {
|
||||
position: relative;
|
||||
|
@ -614,9 +613,9 @@ background-color: #E0E0E0;
|
|||
}
|
||||
.CardOnGraph .tip {
|
||||
position: absolute;
|
||||
background: $mid-gray;
|
||||
background: black;
|
||||
top: 35px;
|
||||
right: 0;
|
||||
left: 0;
|
||||
color: white;
|
||||
border-radius: 4px;
|
||||
font-size:15px !important;
|
||||
|
@ -634,6 +633,7 @@ background-color: #E0E0E0;
|
|||
width:100%;
|
||||
height:47px;
|
||||
position: relative;
|
||||
border-top: 1px solid #BDBDBD;
|
||||
}
|
||||
|
||||
.link-adder a {
|
||||
|
@ -695,9 +695,9 @@ background-color: #E0E0E0;
|
|||
}
|
||||
|
||||
#addLinkInput input{
|
||||
padding: 9px 27px 9px 31px;
|
||||
padding: 9px 7px 9px 31px;
|
||||
height: 12px;
|
||||
width: 210px;
|
||||
width: 198px;
|
||||
margin: 0 0 0 0;
|
||||
border: none;
|
||||
outline: none;
|
||||
|
|
|
@ -668,19 +668,19 @@
|
|||
box-shadow: 0px 3px 3px rgba(0,0,0,0.23), 0 3px 3px rgba(0,0,0,0.16);
|
||||
}
|
||||
|
||||
#navBar {
|
||||
#exploreMapsHeader {
|
||||
position: absolute;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.navBarContainer {
|
||||
.exploreMapsBar {
|
||||
z-index:2;
|
||||
background-color:#FAFAFA;
|
||||
height: 42px;
|
||||
padding-top: 52px;
|
||||
}
|
||||
|
||||
.navBarMenu {
|
||||
.exploreMapsMenu {
|
||||
display: block;
|
||||
width: 100%;
|
||||
height:42px;
|
||||
|
@ -689,29 +689,30 @@
|
|||
text-align: center;
|
||||
}
|
||||
|
||||
.navBarCenter {
|
||||
.exploreMapsCenter {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.navBarButton {
|
||||
color: #757575;
|
||||
.exploreMapsButton {
|
||||
color: #757575;
|
||||
cursor: default;
|
||||
font-weight: normal;
|
||||
font-family: 'din-medium';
|
||||
font-size: 14px;
|
||||
padding: 0 8px;
|
||||
border-bottom: 2px solid rgba(0,0,0,0);
|
||||
height: 14px;
|
||||
padding: 14px 8px 12px 40px;
|
||||
border-bottom: 2px solid rgba(0,0,0,0);
|
||||
display: inline-block;
|
||||
cursor: pointer;
|
||||
position:relative;
|
||||
cursor: pointer;
|
||||
position:relative;
|
||||
}
|
||||
.navBarButton:hover, .navBarButton.active {
|
||||
.exploreMapsButton:hover, .exploreMapsButton.active {
|
||||
text-decoration: none;
|
||||
color: #424242;
|
||||
border-bottom: 2px solid #00BCD4;
|
||||
}
|
||||
|
||||
.navBarButton.mapperButton {
|
||||
.exploreMapsButton.mapperButton {
|
||||
height: 40px;
|
||||
padding: 0;
|
||||
}
|
||||
|
@ -728,69 +729,62 @@
|
|||
}
|
||||
|
||||
|
||||
.navBarButton .navBarIcon {
|
||||
.exploreMapsButton .exploreMapsIcon {
|
||||
background-repeat: no-repeat;
|
||||
width:32px;
|
||||
height:32px;
|
||||
margin-top:5px;
|
||||
margin-left:5px;
|
||||
margin-right: 5px;
|
||||
display: inline-block;
|
||||
vertical-align: top;
|
||||
position:absolute;
|
||||
top:5px;
|
||||
left:5px;
|
||||
}
|
||||
|
||||
.navBarLinkText {
|
||||
padding: 11px 0 12px 0;
|
||||
display: inline-block;
|
||||
}
|
||||
|
||||
.navBarCenter .authedApps .navBarIcon {
|
||||
.exploreMapsCenter .authedApps .exploreMapsIcon {
|
||||
background-image: url(<%= asset_path('user_sprite.png') %>);
|
||||
background-position: 0 -32px;
|
||||
}
|
||||
.navBarCenter .myMaps .navBarIcon {
|
||||
.exploreMapsCenter .myMaps .exploreMapsIcon {
|
||||
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
|
||||
background-position: -32px 0;
|
||||
}
|
||||
.navBarCenter .sharedMaps .navBarIcon {
|
||||
.exploreMapsCenter .sharedMaps .exploreMapsIcon {
|
||||
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
|
||||
background-position: -128px 0;
|
||||
}
|
||||
.navBarCenter .activeMaps .navBarIcon {
|
||||
.exploreMapsCenter .activeMaps .exploreMapsIcon {
|
||||
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
|
||||
background-position: 0 0;
|
||||
}
|
||||
.navBarCenter .featuredMaps .navBarIcon {
|
||||
.exploreMapsCenter .featuredMaps .exploreMapsIcon {
|
||||
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
|
||||
background-position: -96px 0;
|
||||
}
|
||||
.navBarCenter .starredMaps .navBarIcon {
|
||||
.exploreMapsCenter .starredMaps .exploreMapsIcon {
|
||||
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
|
||||
background-position: -96px 0;
|
||||
}
|
||||
.navBarCenter .notificationsLink .navBarIcon {
|
||||
.exploreMapsCenter .notificationsLink .exploreMapsIcon {
|
||||
background-image: url(<%= asset_path 'topright_sprite.png' %>);
|
||||
background-position: -128px 0;
|
||||
}
|
||||
.authedApps:hover .navBarIcon, .authedApps.active .navBarIcon {
|
||||
.authedApps:hover .exploreMapsIcon, .authedApps.active .exploreMapsIcon {
|
||||
background-position-x: -32px;
|
||||
}
|
||||
.myMaps:hover .navBarIcon, .myMaps.active .navBarIcon {
|
||||
.myMaps:hover .exploreMapsIcon, .myMaps.active .exploreMapsIcon {
|
||||
background-position: -32px -32px;
|
||||
}
|
||||
.activeMaps:hover .navBarIcon, .activeMaps.active .navBarIcon {
|
||||
.activeMaps:hover .exploreMapsIcon, .activeMaps.active .exploreMapsIcon {
|
||||
background-position: 0 -32px;
|
||||
}
|
||||
.featuredMaps:hover .navBarIcon, .featuredMaps.active .navBarIcon {
|
||||
.featuredMaps:hover .exploreMapsIcon, .featuredMaps.active .exploreMapsIcon {
|
||||
background-position: -96px -32px;
|
||||
}
|
||||
.starredMaps:hover .navBarIcon, .starredMaps.active .navBarIcon {
|
||||
.starredMaps:hover .exploreMapsIcon, .starredMaps.active .exploreMapsIcon {
|
||||
background-position: -96px -32px;
|
||||
}
|
||||
.sharedMaps:hover .navBarIcon, .sharedMaps.active .navBarIcon {
|
||||
.sharedMaps:hover .exploreMapsIcon, .sharedMaps.active .exploreMapsIcon {
|
||||
background-position: -128px -32px;
|
||||
}
|
||||
.notificationsLink:hover .navBarIcon, .notificationsLink.active .navBarIcon {
|
||||
.notificationsLink:hover .exploreMapsIcon, .notificationsLink.active .exploreMapsIcon {
|
||||
background-position-y: -32px;
|
||||
}
|
||||
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
|
||||
/* Smartphones (portrait and landscape) ----------- the minimum space that two map cards can fit side by side */
|
||||
@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;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,7 +1,4 @@
|
|||
$notifications-border-color: #DDDDDD;
|
||||
$notifications-hover-color: #F6F6F6;
|
||||
$unread_notifications_dot_size: 8px;
|
||||
|
||||
.unread-notifications-dot {
|
||||
width: $unread_notifications_dot_size;
|
||||
height: $unread_notifications_dot_size;
|
||||
|
@ -16,72 +13,13 @@ $unread_notifications_dot_size: 8px;
|
|||
.notificationsIcon {
|
||||
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 {
|
||||
ul.notifications {
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.notificationPage,
|
||||
.notificationsPage {
|
||||
font-family: 'din-regular', Sans-Serif;
|
||||
|
@ -109,9 +47,89 @@ $unread_notifications_dot_size: 8px;
|
|||
.emptyInbox {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.notificationPage {
|
||||
.thirty-two-avatar {
|
||||
|
@ -121,14 +139,14 @@ $unread_notifications_dot_size: 8px;
|
|||
border-radius: 16px;
|
||||
vertical-align: middle;
|
||||
}
|
||||
|
||||
|
||||
.button {
|
||||
line-height: 32px;
|
||||
|
||||
|
||||
img {
|
||||
margin-top: 8px;
|
||||
}
|
||||
|
||||
|
||||
&.decline {
|
||||
background: #DB5D5D;
|
||||
&:hover {
|
||||
|
@ -136,7 +154,7 @@ $unread_notifications_dot_size: 8px;
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
.notification-body {
|
||||
p, div {
|
||||
margin: 1em auto;
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ApplicationCable
|
||||
class Channel < ActionCable::Channel::Base
|
||||
end
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ApplicationCable
|
||||
class Connection < ActionCable::Connection::Base
|
||||
identified_by :current_user
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class MapChannel < ApplicationCable::Channel
|
||||
# Called when the consumer has successfully
|
||||
# become a subscriber of this channel.
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AccessController < ApplicationController
|
||||
before_action :require_user, only: %i[access access_request
|
||||
approve_access approve_access_post
|
||||
deny_access deny_access_post request_access]
|
||||
before_action :set_map, only: %i[access access_request
|
||||
approve_access approve_access_post
|
||||
deny_access deny_access_post request_access]
|
||||
before_action :require_user, only: [:access, :access_request,
|
||||
:approve_access, :approve_access_post,
|
||||
:deny_access, :deny_access_post, :request_access]
|
||||
before_action :set_map, only: [:access, :access_request,
|
||||
:approve_access, :approve_access_post,
|
||||
:deny_access, :deny_access_post, :request_access]
|
||||
after_action :verify_authorized
|
||||
|
||||
# GET maps/:id/request_access
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V1
|
||||
class DeprecatedController < ApplicationController
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V2
|
||||
class MappingsController < WithUpdatesController
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V2
|
||||
class MapsController < WithUpdatesController
|
||||
def searchable_columns
|
||||
%i[name desc]
|
||||
[:name, :desc]
|
||||
end
|
||||
|
||||
def apply_filters(collection)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V2
|
||||
class MetacodesController < RestfulController
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V2
|
||||
class RestfulController < ActionController::Base
|
||||
|
@ -8,7 +7,7 @@ module Api
|
|||
|
||||
snorlax_used_rest!
|
||||
|
||||
before_action :load_resource, only: %i[show update destroy]
|
||||
before_action :load_resource, only: [:show, :update, :destroy]
|
||||
after_action :verify_authorized
|
||||
|
||||
def index
|
||||
|
@ -92,7 +91,7 @@ module Api
|
|||
end
|
||||
|
||||
def doorkeeper_user
|
||||
return if doorkeeper_token.blank?
|
||||
return unless doorkeeper_token.present?
|
||||
doorkeeper_render_error unless valid_doorkeeper_token?
|
||||
@doorkeeper_user ||= User.find(doorkeeper_token.resource_owner_id)
|
||||
end
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V2
|
||||
class SessionsController < ApplicationController
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V2
|
||||
class StarsController < RestfulController
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V2
|
||||
class SynapsesController < WithUpdatesController
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V2
|
||||
class TokensController < RestfulController
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V2
|
||||
class TopicsController < WithUpdatesController
|
||||
def searchable_columns
|
||||
%i[name desc link]
|
||||
[:name, :desc, :link]
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V2
|
||||
class UsersController < RestfulController
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Api
|
||||
module V2
|
||||
class WithUpdatesController < RestfulController
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ApplicationController < ActionController::Base
|
||||
include ApplicationHelper
|
||||
include Pundit
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ExploreController < ApplicationController
|
||||
before_action :require_authentication, only: %i[mine shared starred]
|
||||
before_action :require_authentication, only: [:mine, :shared, :starred]
|
||||
before_action :authorize_explore
|
||||
after_action :verify_authorized
|
||||
after_action :verify_policy_scoped
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
# bad code that should be checked over before entering one of the
|
||||
# nice files from the right side of this repo
|
||||
class HacksController < ApplicationController
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class MainController < ApplicationController
|
||||
before_action :authorize_main
|
||||
after_action :verify_authorized
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
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_policy_scoped, only: :index
|
||||
|
||||
|
|
|
@ -1,10 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class MapsController < ApplicationController
|
||||
before_action :require_user, only: %i[create update destroy events follow unfollow]
|
||||
before_action :set_map, only: %i[show conversation update destroy
|
||||
contains events export
|
||||
follow unfollow unfollow_from_email]
|
||||
before_action :require_user, only: [:create, :update, :destroy, :events, :follow, :unfollow]
|
||||
before_action :set_map, only: [:show, :conversation, :update, :destroy, :contains, :events, :export, :follow, :unfollow, :unfollow_from_email]
|
||||
after_action :verify_authorized
|
||||
|
||||
# GET maps/:id
|
||||
|
@ -26,7 +23,7 @@ class MapsController < ApplicationController
|
|||
format.ttl { redirect_to action: :export, format: :ttl }
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
# GET maps/:id/conversation
|
||||
def conversation
|
||||
respond_to do |format|
|
||||
|
@ -143,7 +140,7 @@ class MapsController < ApplicationController
|
|||
|
||||
# POST maps/:id/follow
|
||||
def follow
|
||||
follow = FollowService.follow(@map, current_user, 'followed')
|
||||
follow = FollowService.follow(@map, current_user, 'followed')
|
||||
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
|
@ -158,7 +155,7 @@ class MapsController < ApplicationController
|
|||
|
||||
# POST maps/:id/unfollow
|
||||
def unfollow
|
||||
FollowService.unfollow(@map, current_user)
|
||||
FollowService.unfollow(@map, current_user)
|
||||
|
||||
respond_to do |format|
|
||||
format.json do
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class MessagesController < ApplicationController
|
||||
before_action :require_user, except: [:show]
|
||||
after_action :verify_authorized
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class MetacodeSetsController < ApplicationController
|
||||
before_action :require_admin
|
||||
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class MetacodesController < ApplicationController
|
||||
before_action :require_admin, except: %i[index show]
|
||||
before_action :set_metacode, only: %i[edit update]
|
||||
before_action :require_admin, except: [:index, :show]
|
||||
before_action :set_metacode, only: [:edit, :update]
|
||||
|
||||
# GET /metacodes
|
||||
# GET /metacodes.json
|
||||
|
|
|
@ -1,23 +1,18 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class NotificationsController < ApplicationController
|
||||
before_action :set_receipts, only: %i[index show mark_read mark_unread]
|
||||
before_action :set_notification, only: %i[show mark_read mark_unread]
|
||||
before_action :set_receipt, only: %i[show mark_read mark_unread]
|
||||
before_action :set_receipts, only: [:index, :show, :mark_read, :mark_unread]
|
||||
before_action :set_notification, only: [:show, :mark_read, :mark_unread]
|
||||
before_action :set_receipt, only: [:show, :mark_read, :mark_unread]
|
||||
|
||||
def index
|
||||
@notifications = current_user.mailbox.notifications.page(params[:page]).per(25)
|
||||
|
||||
respond_to do |format|
|
||||
format.html
|
||||
format.json do
|
||||
notifications = @notifications.map do |notification|
|
||||
render json: @notifications.map do |notification|
|
||||
receipt = @receipts.find_by(notification_id: notification.id)
|
||||
NotificationDecorator.decorate(notification, receipt)
|
||||
end
|
||||
if !notifications.empty?
|
||||
render json: notifications
|
||||
else
|
||||
render json: [].to_json
|
||||
notification.as_json.merge(is_read: receipt.is_read)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -28,18 +23,20 @@ class NotificationsController < ApplicationController
|
|||
respond_to do |format|
|
||||
format.html do
|
||||
case @notification.notification_code
|
||||
when MAP_ACCESS_APPROVED, MAP_INVITE_TO_EDIT
|
||||
redirect_to map_path(@notification.notified_object.map)
|
||||
when TOPIC_ADDED_TO_MAP
|
||||
redirect_to map_path(@notification.notified_object.map)
|
||||
when TOPIC_CONNECTED_1
|
||||
redirect_to topic_path(@notification.notified_object.topic1)
|
||||
when TOPIC_CONNECTED_2
|
||||
redirect_to topic_path(@notification.notified_object.topic2)
|
||||
when MAP_ACCESS_APPROVED, MAP_INVITE_TO_EDIT
|
||||
redirect_to map_path(@notification.notified_object.map)
|
||||
when TOPIC_ADDED_TO_MAP
|
||||
redirect_to map_path(@notification.notified_object.map)
|
||||
when TOPIC_CONNECTED_1
|
||||
redirect_to topic_path(@notification.notified_object.topic1)
|
||||
when TOPIC_CONNECTED_2
|
||||
redirect_to topic_path(@notification.notified_object.topic2)
|
||||
end
|
||||
end
|
||||
format.json do
|
||||
render json: NotificationDecorator.decorate(@notification, @receipt)
|
||||
render json: @notification.as_json.merge(
|
||||
is_read: @receipt.is_read
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -49,7 +46,9 @@ class NotificationsController < ApplicationController
|
|||
respond_to do |format|
|
||||
format.js
|
||||
format.json do
|
||||
render json: NotificationDecorator.decorate(@notification, @receipt)
|
||||
render json: @notification.as_json.merge(
|
||||
is_read: @receipt.is_read
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -59,7 +58,9 @@ class NotificationsController < ApplicationController
|
|||
respond_to do |format|
|
||||
format.js
|
||||
format.json do
|
||||
render json: NotificationDecorator.decorate(@notification, @receipt)
|
||||
render json: @notification.as_json.merge(
|
||||
is_read: @receipt.is_read
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class SearchController < ApplicationController
|
||||
include TopicsHelper
|
||||
include MapsHelper
|
||||
|
@ -8,7 +7,7 @@ class SearchController < ApplicationController
|
|||
|
||||
before_action :authorize_search
|
||||
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
|
||||
def topics
|
||||
|
@ -141,13 +140,13 @@ class SearchController < ApplicationController
|
|||
topic1id = params[:topic1id]
|
||||
topic2id = params[:topic2id]
|
||||
|
||||
if term.present?
|
||||
if term && !term.empty?
|
||||
@synapses = policy_scope(Synapse)
|
||||
.where('LOWER("desc") like ?', '%' + term.downcase.strip + '%')
|
||||
.order('"desc"')
|
||||
|
||||
@synapses = @synapses.uniq(&:desc)
|
||||
elsif topic1id.present?
|
||||
elsif topic1id && !topic1id.empty?
|
||||
one = policy_scope(Synapse).where(topic1_id: topic1id, topic2_id: topic2id)
|
||||
two = policy_scope(Synapse).where(topic2_id: topic1id, topic1_id: topic2id)
|
||||
@synapses = one + two
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class StarsController < ApplicationController
|
||||
before_action :require_user
|
||||
before_action :set_map
|
||||
|
|
|
@ -1,9 +1,8 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class SynapsesController < ApplicationController
|
||||
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_policy_scoped, only: :index
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class TokensController < ApplicationController
|
||||
before_action :require_user, only: [:new]
|
||||
|
||||
|
|
|
@ -1,12 +1,11 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class TopicsController < ApplicationController
|
||||
include TopicsHelper
|
||||
|
||||
before_action :require_user, only: %i[create update destroy follow unfollow]
|
||||
before_action :set_topic, only: %i[show update relative_numbers
|
||||
relatives network destroy
|
||||
follow unfollow unfollow_from_email]
|
||||
before_action :require_user, only: [:create, :update, :destroy, :follow, :unfollow]
|
||||
before_action :set_topic, only: [:show, :update, :relative_numbers,
|
||||
:relatives, :network, :destroy,
|
||||
:follow, :unfollow, :unfollow_from_email]
|
||||
after_action :verify_authorized, except: :autocomplete_topic
|
||||
|
||||
respond_to :html, :js, :json
|
||||
|
@ -14,7 +13,7 @@ class TopicsController < ApplicationController
|
|||
# GET /topics/autocomplete_topic
|
||||
def autocomplete_topic
|
||||
term = params[:term]
|
||||
if term.present?
|
||||
if term && !term.empty?
|
||||
topics = policy_scope(Topic)
|
||||
.where('LOWER("name") like ?', term.downcase + '%')
|
||||
.order('"name"')
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Users
|
||||
class PasswordsController < Devise::PasswordsController
|
||||
protected
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Users
|
||||
class RegistrationsController < Devise::RegistrationsController
|
||||
before_action :configure_sign_up_params, only: [:create]
|
||||
|
@ -30,7 +29,7 @@ module Users
|
|||
end
|
||||
|
||||
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
|
||||
|
||||
def configure_account_update_params
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Users
|
||||
class SessionsController < Devise::SessionsController
|
||||
after_action :store_location, only: [:new]
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
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
|
||||
|
||||
|
@ -24,15 +23,15 @@ class UsersController < ApplicationController
|
|||
if user_params[:password] == '' && user_params[:password_confirmation] == ''
|
||||
# not trying to change the password
|
||||
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.save
|
||||
bypass_sign_in(@user)
|
||||
sign_in(@user, bypass: true)
|
||||
respond_to do |format|
|
||||
format.html { redirect_to root_url, notice: 'Settings updated' }
|
||||
end
|
||||
else
|
||||
bypass_sign_in(@user)
|
||||
sign_in(@user, bypass: true)
|
||||
respond_to do |format|
|
||||
format.html { redirect_to edit_user_path(@user), notice: @user.errors.to_a[0] }
|
||||
end
|
||||
|
@ -42,7 +41,7 @@ class UsersController < ApplicationController
|
|||
correct_pass = @user.valid_password?(params[:current_password])
|
||||
|
||||
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.save
|
||||
sign_in(@user, bypass: true)
|
||||
|
@ -101,7 +100,7 @@ class UsersController < ApplicationController
|
|||
@user.settings.metacode_focus = params[:value]
|
||||
@user.save
|
||||
respond_to do |format|
|
||||
format.json { render json: { success: 'success' } }
|
||||
format.json { render json: { success: "success" }}
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -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
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ApplicationHelper
|
||||
def invite_link
|
||||
"#{request.base_url}/join" + (current_user ? "?code=#{current_user.code}" : '')
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module ContentHelper
|
||||
def resource_name
|
||||
:user
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module DeviseHelper
|
||||
def devise_error_messages!
|
||||
resource.errors.to_a[0]
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module InMetacodeSetsHelper
|
||||
end
|
||||
|
|
|
@ -1,4 +1,3 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module MainHelper
|
||||
end
|
||||
|
|
|
@ -1,5 +1,3 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module MapMailerHelper
|
||||
def access_approved_subject(map)
|
||||
map.name + ' - access approved'
|
||||
|
@ -7,9 +5,9 @@ module MapMailerHelper
|
|||
|
||||
def access_request_subject(map)
|
||||
map.name + ' - request to edit'
|
||||
end
|
||||
end
|
||||
|
||||
def invite_to_edit_subject(map)
|
||||
map.name + ' - invited to edit'
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,4 +1,3 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module MappingHelper
|
||||
end
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module MapsHelper
|
||||
# JSON autocomplete format for typeahead
|
||||
def autocomplete_map_array_json(maps)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module MetacodesHelper
|
||||
def metacodeset
|
||||
metacodes = current_user.settings.metacodes
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module SynapsesHelper
|
||||
## this one is for building our custom JSON autocomplete format for typeahead
|
||||
def autocomplete_synapse_generic_json(unique)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module TopicMailerHelper
|
||||
def added_to_map_subject(topic, map)
|
||||
topic.name + ' was added to map ' + map.name
|
||||
|
@ -8,4 +7,4 @@ module TopicMailerHelper
|
|||
def connected_subject(topic)
|
||||
'new synapse to topic ' + topic.name
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module TopicsHelper
|
||||
## this one is for building our custom JSON autocomplete format for typeahead
|
||||
def autocomplete_array_json(topics)
|
||||
|
@ -17,7 +16,7 @@ module TopicsHelper
|
|||
|
||||
rtype: is_map ? 'map' : 'topic',
|
||||
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,
|
||||
typeImageURL: is_map ? metamap_metacode.icon : t.metacode.icon,
|
||||
mapCount: is_map ? 0 : t.maps.count,
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module UsersHelper
|
||||
# build custom json autocomplete for typeahead
|
||||
def autocomplete_user_array_json(users)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ApplicationMailer < ActionMailer::Base
|
||||
default from: 'team@metamaps.cc'
|
||||
layout 'mailer'
|
||||
|
@ -7,24 +6,24 @@ class ApplicationMailer < ActionMailer::Base
|
|||
class << self
|
||||
def mail_for_notification(notification)
|
||||
case notification.notification_code
|
||||
when MAP_ACCESS_REQUEST
|
||||
request = notification.notified_object
|
||||
MapMailer.access_request(request)
|
||||
when MAP_ACCESS_APPROVED
|
||||
request = notification.notified_object
|
||||
MapMailer.access_approved(request)
|
||||
when MAP_INVITE_TO_EDIT
|
||||
user_map = notification.notified_object
|
||||
MapMailer.invite_to_edit(user_map)
|
||||
when TOPIC_ADDED_TO_MAP
|
||||
event = notification.notified_object
|
||||
TopicMailer.added_to_map(event, notification.recipients[0])
|
||||
when TOPIC_CONNECTED_1
|
||||
synapse = notification.notified_object
|
||||
TopicMailer.connected(synapse, synapse.topic1, notification.recipients[0])
|
||||
when TOPIC_CONNECTED_2
|
||||
synapse = notification.notified_object
|
||||
TopicMailer.connected(synapse, synapse.topic2, notification.recipients[0])
|
||||
when MAP_ACCESS_REQUEST
|
||||
request = notification.notified_object
|
||||
MapMailer.access_request(request)
|
||||
when MAP_ACCESS_APPROVED
|
||||
request = notification.notified_object
|
||||
MapMailer.access_approved(request)
|
||||
when MAP_INVITE_TO_EDIT
|
||||
user_map = notification.notified_object
|
||||
MapMailer.invite_to_edit(user_map)
|
||||
when TOPIC_ADDED_TO_MAP
|
||||
event = notification.notified_object
|
||||
TopicMailer.added_to_map(event, notification.recipients[0])
|
||||
when TOPIC_CONNECTED_1
|
||||
synapse = notification.notified_object
|
||||
TopicMailer.connected(synapse, synapse.topic1, notification.recipients[0])
|
||||
when TOPIC_CONNECTED_2
|
||||
synapse = notification.notified_object
|
||||
TopicMailer.connected(synapse, synapse.topic2, notification.recipients[0])
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class MapActivityMailer < ApplicationMailer
|
||||
default from: 'team@metamaps.cc'
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class MapMailer < ApplicationMailer
|
||||
include MapMailerHelper
|
||||
default from: 'team@metamaps.cc'
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class TopicMailer < ApplicationMailer
|
||||
include TopicMailerHelper
|
||||
default from: 'team@metamaps.cc'
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class AccessRequest < ApplicationRecord
|
||||
belongs_to :user
|
||||
belongs_to :map
|
||||
has_one :user_map
|
||||
|
||||
|
||||
after_create :after_created_async
|
||||
|
||||
def approve
|
||||
|
@ -28,9 +27,9 @@ class AccessRequest < ApplicationRecord
|
|||
Mailboxer::Receipt.where(notification: notification).update_all(is_read: true)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
protected
|
||||
|
||||
|
||||
def after_created_async
|
||||
NotificationService.access_request(self)
|
||||
end
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class ApplicationRecord < ActiveRecord::Base
|
||||
self.abstract_class = true
|
||||
end
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Attachment < ApplicationRecord
|
||||
belongs_to :attachable, polymorphic: true
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Attachable
|
||||
extend ActiveSupport::Concern
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Routing
|
||||
extend ActiveSupport::Concern
|
||||
include Rails.application.routes.url_helpers
|
||||
|
|
|
@ -1,17 +1,16 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
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
|
||||
topic_added_to_map topic_moved_on_map topic_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 :map
|
||||
belongs_to :user
|
||||
|
||||
scope :chronologically, (-> { order('created_at asc') })
|
||||
scope :chronologically, -> { order('created_at asc') }
|
||||
|
||||
after_create :notify_webhooks!, if: :map
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Events
|
||||
class ConversationStartedOnMap < Event
|
||||
# after_create :notify_users!
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Events
|
||||
class SynapseAddedToMap < Event
|
||||
# after_create :notify_users!
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Events
|
||||
class SynapseRemovedFromMap < Event
|
||||
# after_create :notify_users!
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Events
|
||||
class SynapseUpdated < Event
|
||||
# after_create :notify_users!
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Events
|
||||
class TopicAddedToMap < Event
|
||||
after_create :notify_users!
|
||||
|
@ -11,7 +10,7 @@ module Events
|
|||
user: user,
|
||||
meta: meta)
|
||||
end
|
||||
|
||||
|
||||
def notify_users!
|
||||
# in the future, notify followers of both the topic, and the map
|
||||
NotificationService.notify_followers(eventable, TOPIC_ADDED_TO_MAP, self)
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Events
|
||||
class TopicMovedOnMap < Event
|
||||
# after_create :notify_users!
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Events
|
||||
class TopicRemovedFromMap < Event
|
||||
# after_create :notify_users!
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Events
|
||||
class TopicUpdated < Event
|
||||
# after_create :notify_users!
|
||||
#after_create :notify_users!
|
||||
|
||||
def self.publish!(topic, user, meta)
|
||||
create!(kind: 'topic_updated',
|
||||
|
@ -10,7 +9,7 @@ module Events
|
|||
user: user,
|
||||
meta: meta)
|
||||
end
|
||||
|
||||
|
||||
def notify_users!
|
||||
NotificationService.notify_followers(eventable, 'topic_updated', self)
|
||||
end
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Events
|
||||
class UserNotPresentOnMap < Event
|
||||
# after_create :notify_users!
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
module Events
|
||||
class UserPresentOnMap < Event
|
||||
# after_create :notify_users!
|
||||
|
|
|
@ -1,21 +1,19 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Follow < ApplicationRecord
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :followed, polymorphic: true
|
||||
has_one :follow_reason, dependent: :destroy
|
||||
|
||||
|
||||
validates :user, presence: true
|
||||
validates :followed, presence: true
|
||||
validates :user, uniqueness: { scope: :followed, message: 'This entity is already followed by this user' }
|
||||
|
||||
|
||||
after_create :add_subsetting
|
||||
|
||||
scope :active, (-> { where(muted: false) })
|
||||
|
||||
|
||||
private
|
||||
|
||||
def add_subsetting
|
||||
FollowReason.create!(follow: self)
|
||||
follow_reason = FollowReason.create!(follow: self)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,13 +1,12 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
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
|
||||
|
||||
|
||||
validates :follow, presence: true
|
||||
|
||||
|
||||
def has_reason
|
||||
created || commented || contributed || followed || shared_on || starred
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class InMetacodeSet < ApplicationRecord
|
||||
belongs_to :metacode, class_name: 'Metacode', foreign_key: 'metacode_id'
|
||||
belongs_to :metacode_set, class_name: 'MetacodeSet', foreign_key: 'metacode_set_id'
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Map < ApplicationRecord
|
||||
ATTRS_TO_WATCH = %w[name desc permission].freeze
|
||||
ATTRS_TO_WATCH = %w(name desc permission).freeze
|
||||
|
||||
belongs_to :user
|
||||
belongs_to :source, class_name: :Map
|
||||
|
@ -16,7 +15,7 @@ class Map < ApplicationRecord
|
|||
has_many :messages, as: :resource, dependent: :destroy
|
||||
has_many :stars, 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 :user_maps, dependent: :destroy
|
||||
|
@ -43,7 +42,6 @@ class Map < ApplicationRecord
|
|||
after_create :after_created
|
||||
after_update :after_updated
|
||||
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: :synapses, prefix: :synapse
|
||||
|
@ -90,10 +88,10 @@ class Map < ApplicationRecord
|
|||
|
||||
def as_json(_options = {})
|
||||
json = super(
|
||||
methods: %i[user_name user_image star_count topic_count synapse_count
|
||||
contributor_count collaborator_ids screenshot_url],
|
||||
except: %i[screenshot_content_type screenshot_file_size screenshot_file_name
|
||||
screenshot_updated_at]
|
||||
methods: [:user_name, :user_image, :star_count, :topic_count, :synapse_count,
|
||||
:contributor_count, :collaborator_ids, :screenshot_url],
|
||||
except: [:screenshot_content_type, :screenshot_file_size, :screenshot_file_name,
|
||||
:screenshot_updated_at]
|
||||
)
|
||||
json[:created_at_clean] = created_at_str
|
||||
json[:updated_at_clean] = updated_at_str
|
||||
|
@ -134,16 +132,16 @@ class Map < ApplicationRecord
|
|||
end
|
||||
removed.compact
|
||||
end
|
||||
|
||||
|
||||
def update_deferring_topics_and_synapses
|
||||
Topic.where(defer_to_map_id: id).update(permission: permission)
|
||||
Synapse.where(defer_to_map_id: id).update(permission: permission)
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
|
||||
def after_created
|
||||
FollowService.follow(self, user, 'created')
|
||||
FollowService.follow(self, self.user, 'created')
|
||||
# notify users following the map creator
|
||||
end
|
||||
|
||||
|
@ -151,18 +149,13 @@ class Map < ApplicationRecord
|
|||
return unless ATTRS_TO_WATCH.any? { |k| changed_attributes.key?(k) }
|
||||
ActionCable.server.broadcast 'map_' + id.to_s, type: 'mapUpdated'
|
||||
end
|
||||
|
||||
|
||||
def after_updated_async
|
||||
return unless ATTRS_TO_WATCH.any? { |k| changed_attributes.key?(k) }
|
||||
FollowService.follow(self, updated_by, 'contributed')
|
||||
# NotificationService.notify_followers(self, 'map_updated', changed_attributes)
|
||||
# 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)
|
||||
if ATTRS_TO_WATCH.any? { |k| changed_attributes.key?(k) }
|
||||
FollowService.follow(self, updated_by, 'contributed')
|
||||
# NotificationService.notify_followers(self, 'map_updated', changed_attributes)
|
||||
# or better yet publish an event
|
||||
end
|
||||
end
|
||||
handle_asynchronously :after_updated_async
|
||||
end
|
||||
|
|
|
@ -1,8 +1,7 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Mapping < ApplicationRecord
|
||||
scope :topicmapping, (-> { where(mappable_type: :Topic) })
|
||||
scope :synapsemapping, (-> { where(mappable_type: :Synapse) })
|
||||
scope :topicmapping, -> { where(mappable_type: :Topic) }
|
||||
scope :synapsemapping, -> { where(mappable_type: :Synapse) }
|
||||
|
||||
belongs_to :mappable, polymorphic: true
|
||||
belongs_to :map, class_name: 'Map', foreign_key: 'map_id', touch: true
|
||||
|
@ -25,7 +24,7 @@ class Mapping < ApplicationRecord
|
|||
end
|
||||
|
||||
def as_json(_options = {})
|
||||
super(methods: %i[user_name user_image])
|
||||
super(methods: [:user_name, :user_image])
|
||||
end
|
||||
|
||||
def after_created
|
||||
|
@ -38,8 +37,8 @@ class Mapping < ApplicationRecord
|
|||
'map_' + map.id.to_s,
|
||||
type: 'synapseAdded',
|
||||
synapse: mappable.filtered,
|
||||
topic1: mappable.topic1&.filtered,
|
||||
topic2: mappable.topic2&.filtered,
|
||||
topic1: mappable.topic1.filtered,
|
||||
topic2: mappable.topic2.filtered,
|
||||
mapping_id: id
|
||||
)
|
||||
meta = { 'mapping_id': id }
|
||||
|
@ -53,17 +52,17 @@ class Mapping < ApplicationRecord
|
|||
handle_asynchronously :after_created_async
|
||||
|
||||
def after_updated
|
||||
return unless (mappable_type == 'Topic') && (xloc_changed? || yloc_changed?)
|
||||
meta = { 'x': xloc, 'y': yloc, 'mapping_id': id }
|
||||
Events::TopicMovedOnMap.publish!(mappable, map, updated_by, meta)
|
||||
ActionCable.server.broadcast('map_' + map.id.to_s, type: 'topicMoved',
|
||||
id: mappable.id, mapping_id: id,
|
||||
x: xloc, y: yloc)
|
||||
if (mappable_type == 'Topic') && (xloc_changed? || yloc_changed?)
|
||||
meta = { 'x': xloc, 'y': yloc, 'mapping_id': id }
|
||||
Events::TopicMovedOnMap.publish!(mappable, map, updated_by, meta)
|
||||
ActionCable.server.broadcast 'map_' + map.id.to_s, type: 'topicMoved', id: mappable.id, mapping_id: id, x: xloc, y: yloc
|
||||
end
|
||||
end
|
||||
|
||||
def after_updated_async
|
||||
return unless (mappable_type == 'Topic') && (xloc_changed? || yloc_changed?)
|
||||
FollowService.follow(map, updated_by, 'contributed')
|
||||
if (mappable_type == 'Topic') && (xloc_changed? || yloc_changed?)
|
||||
FollowService.follow(map, updated_by, 'contributed')
|
||||
end
|
||||
end
|
||||
handle_asynchronously :after_updated_async
|
||||
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Message < ApplicationRecord
|
||||
belongs_to :user
|
||||
belongs_to :resource, polymorphic: true
|
||||
|
@ -7,14 +6,15 @@ class Message < ApplicationRecord
|
|||
delegate :name, to: :user, prefix: true
|
||||
|
||||
after_create :after_created
|
||||
# after_create :after_created_async
|
||||
#after_create :after_created_async
|
||||
|
||||
|
||||
def user_image
|
||||
user.image.url
|
||||
end
|
||||
|
||||
def as_json(_options = {})
|
||||
json = super(methods: %i[user_name user_image])
|
||||
json = super(methods: [:user_name, :user_image])
|
||||
json
|
||||
end
|
||||
|
||||
|
|
|
@ -1,16 +1,17 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Metacode < ApplicationRecord
|
||||
has_many :in_metacode_sets
|
||||
has_many :metacode_sets, through: :in_metacode_sets
|
||||
has_many :topics
|
||||
|
||||
# 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'
|
||||
|
||||
# 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 :manual_icon_https
|
||||
|
@ -29,13 +30,15 @@ class Metacode < ApplicationRecord
|
|||
def as_json(options = {})
|
||||
default = super(options)
|
||||
default[:icon] = icon
|
||||
default.except(
|
||||
'aws_icon_file_name', 'aws_icon_content_type', 'aws_icon_file_size', 'aws_icon_updated_at',
|
||||
'manual_icon'
|
||||
)
|
||||
default.except('aws_icon_file_name', 'aws_icon_content_type', 'aws_icon_file_size', 'aws_icon_updated_at', 'manual_icon')
|
||||
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
|
||||
false
|
||||
end
|
||||
|
@ -52,9 +55,10 @@ class Metacode < ApplicationRecord
|
|||
end
|
||||
|
||||
def manual_icon_https
|
||||
return if manual_icon.blank?
|
||||
unless manual_icon.starts_with? 'https'
|
||||
errors.add(:base, 'Manual icon must begin with https')
|
||||
if manual_icon.present?
|
||||
unless manual_icon.starts_with? 'https'
|
||||
errors.add(:base, 'Manual icon must begin with https')
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class MetacodeSet < ApplicationRecord
|
||||
belongs_to :user
|
||||
has_many :in_metacode_sets
|
||||
|
|
|
@ -1,18 +1,13 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class PermittedParams
|
||||
%w[map synapse topic mapping token].each do |kind|
|
||||
class PermittedParams < Struct.new(:params)
|
||||
%w(map synapse topic mapping token).each do |kind|
|
||||
define_method(kind) do
|
||||
permitted_attributes = send("#{kind}_attributes")
|
||||
@params.require(kind).permit(*permitted_attributes)
|
||||
params.require(kind).permit(*permitted_attributes)
|
||||
end
|
||||
alias_method :"api_#{kind}", kind.to_sym
|
||||
end
|
||||
|
||||
def initialize(params)
|
||||
@params = params
|
||||
end
|
||||
|
||||
alias read_attribute_for_serialization send
|
||||
|
||||
def token_attributes
|
||||
|
@ -20,18 +15,18 @@ class PermittedParams
|
|||
end
|
||||
|
||||
def map_attributes
|
||||
%i[name desc permission arranged]
|
||||
[:name, :desc, :permission, :arranged]
|
||||
end
|
||||
|
||||
def synapse_attributes
|
||||
%i[desc category weight permission topic1_id topic2_id]
|
||||
[:desc, :category, :weight, :permission, :topic1_id, :topic2_id]
|
||||
end
|
||||
|
||||
def topic_attributes
|
||||
%i[name desc link permission metacode_id]
|
||||
[:name, :desc, :link, :permission, :metacode_id]
|
||||
end
|
||||
|
||||
def mapping_attributes
|
||||
%i[xloc yloc map_id mappable_type mappable_id]
|
||||
[:xloc, :yloc, :map_id, :mappable_type, :mappable_id]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,21 +1,20 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Star < ApplicationRecord
|
||||
class Star < ActiveRecord::Base
|
||||
belongs_to :user
|
||||
belongs_to :map
|
||||
validates :map, uniqueness: { scope: :user, message: 'You have already starred this map' }
|
||||
|
||||
# after_create :after_created_async
|
||||
# before_destroy :before_destroyed
|
||||
|
||||
#after_create :after_created_async
|
||||
#before_destroy :before_destroyed
|
||||
|
||||
protected
|
||||
|
||||
|
||||
def after_created_async
|
||||
FollowService.follow(map, user, 'starred')
|
||||
NotificationService.notify_followers(map, 'map_starred', self, 'created')
|
||||
end
|
||||
handle_asynchronously :after_created_async
|
||||
|
||||
|
||||
def before_destroyed
|
||||
FollowService.remove_reason(map, user, 'starred')
|
||||
end
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
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 :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 }
|
||||
|
||||
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))
|
||||
end)
|
||||
}
|
||||
|
||||
before_create :set_perm_by_defer
|
||||
after_create :after_created_async
|
||||
|
@ -39,7 +38,7 @@ class Synapse < ApplicationRecord
|
|||
|
||||
def collaborator_ids
|
||||
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
|
||||
[]
|
||||
end
|
||||
|
@ -55,7 +54,7 @@ class Synapse < ApplicationRecord
|
|||
end
|
||||
|
||||
def as_json(_options = {})
|
||||
super(methods: %i[user_name user_image collaborator_ids])
|
||||
super(methods: [:user_name, :user_image, :collaborator_ids])
|
||||
end
|
||||
|
||||
def as_rdf
|
||||
|
@ -73,7 +72,7 @@ class Synapse < ApplicationRecord
|
|||
protected
|
||||
|
||||
def set_perm_by_defer
|
||||
defer_to_map&.permission
|
||||
permission = defer_to_map.permission if defer_to_map
|
||||
end
|
||||
|
||||
def after_created_async
|
||||
|
@ -83,21 +82,21 @@ class Synapse < ApplicationRecord
|
|||
handle_asynchronously :after_created_async
|
||||
|
||||
def after_updated
|
||||
return unless ATTRS_TO_WATCH.any? { |k| changed_attributes.key?(k) }
|
||||
|
||||
new = 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['changed'] = changed_attributes.keys.select { |k| ATTRS_TO_WATCH.include?(k) }
|
||||
Events::SynapseUpdated.publish!(self, updated_by, meta)
|
||||
maps.each do |map|
|
||||
ActionCable.server.broadcast 'map_' + map.id.to_s, type: 'synapseUpdated', id: id
|
||||
if ATTRS_TO_WATCH.any? { |k| changed_attributes.key?(k) }
|
||||
new = 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['changed'] = changed_attributes.keys.select { |k| ATTRS_TO_WATCH.include?(k) }
|
||||
Events::SynapseUpdated.publish!(self, updated_by, meta)
|
||||
maps.each do |map|
|
||||
ActionCable.server.broadcast 'map_' + map.id.to_s, type: 'synapseUpdated', id: id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
def before_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(topic2, 'topic_disconnected', self)
|
||||
#NotificationService.notify_followers(topic1, 'topic_disconnected', self)
|
||||
#NotificationService.notify_followers(topic2, 'topic_disconnected', self)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class Token < ApplicationRecord
|
||||
belongs_to :user
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
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 Attachable
|
||||
|
||||
|
@ -17,7 +16,7 @@ class Topic < ApplicationRecord
|
|||
has_many :mappings, as: :mappable, dependent: :destroy
|
||||
has_many :maps, through: :mappings
|
||||
has_many :follows, as: :followed, dependent: :destroy
|
||||
has_many :followers, through: :follows, source: :user
|
||||
has_many :followers, :through => :follows, source: :user
|
||||
|
||||
belongs_to :metacode
|
||||
|
||||
|
@ -26,7 +25,7 @@ class Topic < ApplicationRecord
|
|||
after_create :after_created_async
|
||||
after_update :after_updated
|
||||
after_update :after_updated_async
|
||||
# before_destroy :before_destroyed
|
||||
#before_destroy :before_destroyed
|
||||
|
||||
validates :permission, presence: true
|
||||
validates :permission, inclusion: { in: Perm::ISSIONS.map(&:to_s) }
|
||||
|
@ -39,13 +38,13 @@ class Topic < ApplicationRecord
|
|||
topics1.or(topics2)
|
||||
end
|
||||
|
||||
scope :relatives, (lambda do |topic_id = nil, user = nil|
|
||||
scope :relatives, ->(topic_id = nil, user = nil) {
|
||||
# should only see topics through *visible* synapses
|
||||
# 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(topic2_id: topic_id)).pluck(:topic1_id)
|
||||
where(id: topic_ids.uniq)
|
||||
end)
|
||||
}
|
||||
|
||||
delegate :name, to: :user, prefix: true
|
||||
|
||||
|
@ -65,13 +64,13 @@ class Topic < ApplicationRecord
|
|||
Pundit.policy_scope(user, maps).map(&:name)
|
||||
end
|
||||
|
||||
def inmaps_links(user)
|
||||
def inmapsLinks(user)
|
||||
Pundit.policy_scope(user, maps).map(&:id)
|
||||
end
|
||||
|
||||
def as_json(options = {})
|
||||
super(methods: %i[user_name user_image collaborator_ids])
|
||||
.merge(inmaps: inmaps(options[:user]), inmapsLinks: inmaps_links(options[:user]),
|
||||
super(methods: [:user_name, :user_image, :collaborator_ids])
|
||||
.merge(inmaps: inmaps(options[:user]), inmapsLinks: inmapsLinks(options[:user]),
|
||||
map_count: map_count(options[:user]), synapse_count: synapse_count(options[:user]))
|
||||
end
|
||||
|
||||
|
@ -90,7 +89,7 @@ class Topic < ApplicationRecord
|
|||
|
||||
def collaborator_ids
|
||||
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
|
||||
[]
|
||||
end
|
||||
|
@ -127,9 +126,14 @@ class Topic < ApplicationRecord
|
|||
end
|
||||
end
|
||||
end
|
||||
return output if output_format == 'array'
|
||||
return output.join('; ') if output_format == 'text'
|
||||
raise 'invalid argument to synapses_csv'
|
||||
if output_format == 'array'
|
||||
return output
|
||||
elsif output_format == 'text'
|
||||
return output.join('; ')
|
||||
else
|
||||
raise 'invalid argument to synapses_csv'
|
||||
end
|
||||
output
|
||||
end
|
||||
|
||||
def topic_autocomplete_method
|
||||
|
@ -139,7 +143,7 @@ class Topic < ApplicationRecord
|
|||
protected
|
||||
|
||||
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
|
||||
|
||||
def create_metamap?
|
||||
|
@ -150,35 +154,35 @@ class Topic < ApplicationRecord
|
|||
self.link = Rails.application.routes.url_helpers
|
||||
.map_url(host: ENV['MAILER_DEFAULT_URL'], id: @map.id)
|
||||
end
|
||||
|
||||
|
||||
def after_created_async
|
||||
FollowService.follow(self, user, 'created')
|
||||
FollowService.follow(self, self.user, 'created')
|
||||
# notify users following the topic creator
|
||||
end
|
||||
handle_asynchronously :after_created_async
|
||||
|
||||
def after_updated
|
||||
return unless ATTRS_TO_WATCH.any? { |k| changed_attributes.key?(k) }
|
||||
|
||||
new = 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['changed'] = changed_attributes.keys.select { |k| ATTRS_TO_WATCH.include?(k) }
|
||||
Events::TopicUpdated.publish!(self, updated_by, meta)
|
||||
maps.each do |map|
|
||||
ActionCable.server.broadcast 'map_' + map.id.to_s, type: 'topicUpdated', id: id
|
||||
if ATTRS_TO_WATCH.any? { |k| changed_attributes.key?(k) }
|
||||
new = 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['changed'] = changed_attributes.keys.select { |k| ATTRS_TO_WATCH.include?(k) }
|
||||
Events::TopicUpdated.publish!(self, updated_by, meta)
|
||||
maps.each do |map|
|
||||
ActionCable.server.broadcast 'map_' + map.id.to_s, type: 'topicUpdated', id: id
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
def after_updated_async
|
||||
return unless ATTRS_TO_WATCH.any? { |k| changed_attributes.key?(k) }
|
||||
|
||||
FollowService.follow(self, updated_by, 'contributed')
|
||||
if ATTRS_TO_WATCH.any? { |k| changed_attributes.key?(k) }
|
||||
FollowService.follow(self, updated_by, 'contributed')
|
||||
end
|
||||
end
|
||||
handle_asynchronously :after_updated_async
|
||||
|
||||
def before_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
|
||||
|
|
|
@ -1,5 +1,4 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'open-uri'
|
||||
|
||||
class User < ApplicationRecord
|
||||
|
@ -52,24 +51,26 @@ class User < ApplicationRecord
|
|||
validates_attachment_content_type :image, content_type: %r{\Aimage/.*\Z}
|
||||
|
||||
# override default as_json
|
||||
def as_json(options = {})
|
||||
def as_json(_options = {})
|
||||
json = { id: id,
|
||||
name: name,
|
||||
image: image.url(:sixtyfour),
|
||||
admin: admin }
|
||||
if options[:follows]
|
||||
name: name,
|
||||
image: image.url(:sixtyfour),
|
||||
admin: admin }
|
||||
if (_options[:follows])
|
||||
json['follows'] = {
|
||||
topics: following.active.where(followed_type: 'Topic').to_a.map(&:followed_id),
|
||||
maps: following.active.where(followed_type: 'Map').to_a.map(&:followed_id)
|
||||
topics: following.where(followed_type: 'Topic').to_a.map(&:followed_id),
|
||||
maps: following.where(followed_type: 'Map').to_a.map(&:followed_id)
|
||||
}
|
||||
end
|
||||
if options[:follow_settings]
|
||||
json['follow_topic_on_created'] = settings.follow_topic_on_created == '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_contributed'] = settings.follow_map_on_contributed == '1'
|
||||
if (_options[:follow_settings])
|
||||
json['follow_topic_on_created'] = settings.follow_topic_on_created == "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_contributed'] = settings.follow_map_on_contributed == "1"
|
||||
end
|
||||
if (_options[:email])
|
||||
json['email'] = email
|
||||
end
|
||||
json['email'] = email if options[:email]
|
||||
json
|
||||
end
|
||||
|
||||
|
@ -106,14 +107,10 @@ class User < ApplicationRecord
|
|||
end
|
||||
|
||||
def most_used_metacodes
|
||||
metacode_counts = topics.to_a.each_with_object(Hash.new(0)) do |topic, list_so_far|
|
||||
list_so_far[topic.metacode_id] += 1
|
||||
list_so_far
|
||||
end
|
||||
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)
|
||||
topics.to_a.each_with_object(Hash.new(0)) do |topic, memo|
|
||||
memo[topic.metacode_id] += 1
|
||||
memo
|
||||
end.to_a.sort { |a, b| b[1] <=> a[1] }.map { |i| i[0] }.slice(0, 5)
|
||||
end
|
||||
|
||||
# generate a random 8 letter/digit code that they can use to invite people
|
||||
|
@ -136,20 +133,20 @@ class User < ApplicationRecord
|
|||
end
|
||||
|
||||
def has_map_open(map)
|
||||
latest_event = Event.where(map: map, user: self)
|
||||
.where(kind: %w[user_present_on_map user_not_present_on_map])
|
||||
.order(:created_at)
|
||||
.last
|
||||
latest_event && latest_event.kind == 'user_present_on_map'
|
||||
latestEvent = Event.where(map: map, user: self)
|
||||
.where(kind: ['user_present_on_map', 'user_not_present_on_map'])
|
||||
.order(:created_at)
|
||||
.last
|
||||
latestEvent && latestEvent.kind == 'user_present_on_map'
|
||||
end
|
||||
|
||||
def has_map_with_synapse_open(synapse)
|
||||
synapse.maps.any? { |map| has_map_open(map) }
|
||||
synapse.maps.any?{|map| has_map_open(map)}
|
||||
end
|
||||
|
||||
def settings
|
||||
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
|
||||
end
|
||||
self[:settings]
|
||||
|
|
|
@ -1,10 +1,9 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
class UserMap < ApplicationRecord
|
||||
belongs_to :map
|
||||
belongs_to :user
|
||||
belongs_to :access_request
|
||||
|
||||
|
||||
after_create :after_created_async
|
||||
before_destroy :before_destroyed
|
||||
|
||||
|
@ -13,20 +12,20 @@ class UserMap < ApplicationRecord
|
|||
Mailboxer::Receipt.where(notification: notification).update_all(is_read: true)
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
protected
|
||||
|
||||
|
||||
def after_created_async
|
||||
FollowService.follow(map, user, 'shared_on')
|
||||
if access_request
|
||||
NotificationService.access_approved(access_request)
|
||||
NotificationService.access_approved(self.access_request)
|
||||
else
|
||||
NotificationService.invite_to_edit(self)
|
||||
end
|
||||
# NotificationService.notify_followers(map, 'map_collaborator_added', self, 'shared_on')
|
||||
end
|
||||
handle_asynchronously :after_created_async
|
||||
|
||||
|
||||
def before_destroyed
|
||||
FollowService.remove_reason(map, user, 'shared_on')
|
||||
end
|
||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue