Compare commits

...

189 commits

Author SHA1 Message Date
Devin Howard 98081097b4 Revert "update rails dependencies"
Original commit broke the build, since some dependencies have breaking
changes.

This reverts commit f753392d49.
2018-11-09 07:42:26 -08:00
Devin Howard f753392d49 update rails dependencies 2018-10-17 19:51:51 -07:00
Connor Turland 38a209a970 small bug fix (#1174)
if someone besides one of "us" tried to change their password, and their settings, it wouldn't work

in the typical case it would work fine
2018-03-11 21:57:23 -07:00
Devin Howard bd7bf20810
factory_girl => factory_bot (#1172) 2018-03-10 08:10:09 -08:00
Devin Howard 955ebdd747
Change log level of Metamaps.Debug (#1170)
debug log level is invisible in Chrome by default, which is confusing
2018-02-05 21:35:53 -08:00
Devin Howard fdcd8a93f1 tag 3.6.1 2018-01-24 20:02:28 -08:00
Devin Howard b5c52adf5e update to paperclip 5.2.0 2018-01-24 19:52:33 -08:00
Devin Howard b7761a3627
manual rubocop fixes (#1163) 2018-01-21 14:21:00 -08:00
Devin Howard e0d72fce14
update nokogiri (#1169) 2018-01-21 14:20:21 -08:00
Devin Howard 139fdf8e2b
update rubocop to 0.48.1. We still want to match Code Climate though (#1168) 2018-01-20 14:10:26 -08:00
Devin Howard 4313f6eff8
TopicCard/Desc.spec.js (#1167)
TopicCard/Desc.spec.js
2018-01-20 13:31:36 -08:00
Devin Howard 91c004ebfd
TopicCard/Permission.spec.js (#1166) 2017-12-04 21:06:09 -08:00
Devin Howard 96056f43ef
TopicCard/Title.spec.js (#1165) 2017-12-02 12:45:05 -08:00
Devin Howard 32e58fa8af
tests for TopicCard/index.js (#1164) 2017-11-26 16:13:17 -08:00
Devin Howard 5ebbd87afc
automatic rubocop fixes (#1162) 2017-11-25 11:23:47 -08:00
Devin Howard 006920b686 fix broken experience if forgot password email isn't found 2017-11-13 07:16:25 -08:00
Devin Howard 97448b389f null check in synapse policy 2017-11-13 07:11:48 -08:00
Connor Turland f1ecc9eb0b Merge pull request #1160 from metamaps/bug/map.info.box.closing
event listener was getting lost cuz react
2017-10-26 19:17:42 -04:00
Connor Turland ca2684fcf3 event listener was getting lost cuz react 2017-10-26 19:09:28 -04:00
Connor Turland d9c53514fe Update pull-changes.md 2017-10-25 06:44:20 -04:00
Connor Turland e195b89bbd Merge pull request #1155 from metamaps/bug/fix.emails
fix map activity emails
2017-10-17 12:26:20 -04:00
Connor Turland e66498a861 add logging for delayedJob 2017-10-17 12:20:51 -04:00
Connor Turland 901eb4a513 Update daily_summary.html.erb 2017-10-17 12:06:37 -04:00
Devin Howard cbf44e3dfe add one view test 2017-10-17 08:28:00 -07:00
Connor Turland 8b492d6dc8 made the mistake of not checking all cases 2017-10-17 01:28:07 -04:00
Connor Turland b83f366284 Merge pull request #1151 from metamaps/feature/admin.pages
move admin header to react
2017-10-15 16:05:18 -04:00
Connor Turland 1ac06d973c Merge pull request #1153 from metamaps/feature/follow.created
follow created maps as default setting
2017-10-15 14:08:04 -04:00
Connor Turland 9af3754bc8 follow created maps as default setting
if you are the map creator, we'd like to set you up to be following it by default
2017-10-15 14:07:11 -04:00
Connor Turland 8169f24072 Merge pull request #1150 from metamaps/rake-assets-precompile
run perms:fix on assets:precompile
2017-10-15 11:02:59 -04:00
Connor Turland b9fb4a2829 move admin header to react 2017-10-15 10:56:51 -04:00
Connor Turland 9b52d0e081 fix tests 2017-10-15 10:56:04 -04:00
Devin Howard 14dc3687cd run perms:fix on assets:precompile 2017-10-14 12:02:41 -07:00
Metamaps on Linode 0a6e7918ef fix docs building by reverting raml2html 2017-10-14 14:55:42 -04:00
Metamaps on Linode 4a7595e76d fixup imports 2017-10-14 14:55:42 -04:00
Connor Turland e899179314 Update first-deploy.md 2017-10-14 14:44:10 -04:00
Connor Turland 44fec58985 Merge pull request #1149 from metamaps/feature/reorg.react
reorg code to distinguish between route components and normal ones
2017-10-14 12:38:57 -04:00
Connor Turland 29a25c28a8 distinguish between route components and reusable components 2017-10-14 12:37:48 -04:00
Connor Turland 76c727cd61 Merge pull request #1148 from metamaps/feature/refactor.nav.bar
rename exploreMapsBar into reusable navBar
2017-10-14 12:30:29 -04:00
Connor Turland 693e6f5e10 bug fixes and make active class auto 2017-10-14 12:03:05 -04:00
Connor Turland a1d4c99ff6 abstract exploreMapsBar into reusable navBar 2017-10-13 13:58:21 -04:00
Connor Turland 55f2425501 Merge pull request #1142 from metamaps/feature/notifs.box
Notifications Dropdown
2017-10-13 12:29:21 -04:00
Connor Turland f9c139c19e ruby codeclimate fixes 2017-10-13 12:22:05 -04:00
Connor Turland d51a22c5a9 eslint fixes 2017-10-13 12:13:36 -04:00
Connor Turland 567bc9d69d Merge pull request #1145 from metamaps/feature/lower.case.headings
Switch junto headings to have normal casing (not all uppercase)
2017-10-04 11:22:33 -04:00
Connor Turland 15f512efef improve notificationbox readability 2017-09-29 14:05:39 -04:00
Connor Turland 5e6fb6290c refactor for clarity 2017-09-29 13:06:33 -04:00
Connor Turland 8695297a0f wasn't using the proper serializer causing frontend error 2017-09-29 13:06:19 -04:00
Connor Turland 216a19476b add hover states and empty case 2017-09-28 12:28:33 -04:00
Connor Turland a0c9530c91 Update index.js 2017-09-25 16:01:25 -04:00
Connor Turland 277644f59d improve styling, fix index notifs page 2017-09-25 15:21:04 -04:00
Connor Turland 0ffc01b3fb Merge pull request #1144 from metamaps/feature/hide-learn-markdown
hide "learn markdown" unless you're editing the topic card desc
2017-09-25 14:46:44 -04:00
Devin Howard 9471efb6bd hide "learn markdown" unless you're editing the topic card desc 2017-09-23 13:19:43 -07:00
Connor Turland fc8ac6eef1 nest inconsistent data under data key 2017-09-23 11:20:02 -04:00
Connor Turland 9cc700c64d use decorator pattern for notifs api 2017-09-22 18:38:38 -04:00
Connor Turland 64ffc78f45 add the container for the notifications dropdown 2017-09-19 23:48:46 -04:00
Connor Turland 322da431eb Merge pull request #1139 from metamaps/feature/right.click.react
Right click/context menu redone in React
2017-09-19 11:49:30 -04:00
Connor Turland 3c7c8812a4 tempplate strings and new lines 2017-09-19 11:46:19 -04:00
Connor Turland 0d6963ebb0 eslint 2017-09-19 10:16:14 -04:00
Connor Turland c4d0bf8ce4 clean up jquery ref and strings 2017-09-19 10:02:05 -04:00
Connor Turland 3406f2e04d make render a callback and use async apply for ease of use 2017-09-19 09:58:59 -04:00
Connor Turland a4c905df4e move each li into its own function 2017-09-19 09:04:21 -04:00
Connor Turland 5f1fe4dc3f reimplement shifting menu according to click position 2017-09-19 08:37:00 -04:00
Connor Turland 2515073393 replace old edgeRightClick code 2017-09-19 00:46:23 -04:00
Connor Turland a04cd0d395 call the right callbacks and show in the right context 2017-09-19 00:34:37 -04:00
Connor Turland da9e44afa0 clear the right click menu the right way 2017-09-18 23:49:35 -04:00
Connor Turland e290244404 beginning to come together 2017-09-18 23:30:33 -04:00
Connor Turland 6e1878413f wip right click in react 2017-09-18 21:09:35 -04:00
Connor Turland 77846cfcb7 missing period for consistency 2017-09-18 16:59:52 -04:00
Connor Turland 1ffc513617 Merge pull request #1137 from metamaps/feature/improve.desc
make desc edit area larger and resizable
2017-09-17 16:25:53 -04:00
Connor Turland 3886e62a7b make desc edit area larger and resizable 2017-09-17 09:01:44 -04:00
Devin Howard ad2ba33db6 downgrade redis to 3.3.3
This fixes the following error seen on metamaps.cc:

> *A* `Gem::LoadError` *occurred while* `POST </mappings>` *was processed
> by* `mappings#create`: Specified 'redis' for Action Cable pubsub
> adapter, but the gem is not loaded. Add `gem 'redis'` to your Gemfile
> (and ensure its version is at the minimum required by Action Cable).

Backtrace
----------------

    ```/usr/local/rvm/rubies/ruby-2.3.0/lib/ruby/2.3.0/monitor.rb:214:in
    `mon_synchronize'
    /home/metamaps/metamaps.cc/app/models/mapping.rb:32:in `after_created'
    /home/metamaps/metamaps.cc/app/controllers/mappings_controller.rb:24:in
    `create'```
2017-09-16 13:41:50 -07:00
Devin Howard cf9f54c738 tag v3.5 2017-09-16 12:27:02 -07:00
Connor Turland f323796030 Merge pull request #1132 from metamaps/feature/mod.follow
add active scope to follows model
2017-09-13 22:45:50 -04:00
Connor Turland a080b82e7f Merge pull request #1133 from metamaps/feature/topic.follow
Topic Card Design changes (to include 'follows')
2017-09-13 10:32:44 -04:00
Connor Turland 1174123b60 use scss vars and font fallbacks 2017-09-13 10:31:48 -04:00
Connor Turland 35f77129ad email job needs to respect active as well 2017-09-13 10:20:25 -04:00
Connor Turland a56991aede add exception notifier for failed jobs 2017-09-13 10:18:00 -04:00
Connor Turland 672b456193 add markdown clarifications 2017-09-12 21:37:49 -04:00
Connor Turland 21518c8696 revert react router update and webpack config 2017-09-12 17:07:57 -04:00
Connor Turland 29bf2a23e8 review changes 2017-09-12 17:01:08 -04:00
Connor Turland 61eac509de Merge branch 'develop' into feature/topic.follow 2017-09-10 18:16:11 -04:00
Connor Turland 4cc420eb63 eslint fixes 2017-09-10 18:13:25 -04:00
Connor Turland ec3e09c578 topic card design changes 2017-09-10 17:17:56 -04:00
Devin Howard 3e03e0ebbf update npm/gem dependencies (#1131)
* update npm/gem dependencies

* move to react prop-types package and fix jsdom usage

* fix sinon

* fix test support

* eslint?
2017-09-09 09:38:18 -07:00
Connor Turland 9ab7e7e170 topic card re-org 2017-09-08 16:58:17 -04:00
Connor Turland 5af2b8f216 add active scope to follows model 2017-09-08 13:42:56 -04:00
Connor Turland 8af66b1b2c Merge pull request #1130 from metamaps/feature/release.notifs
make notifs and follows work for all users
2017-09-03 18:44:33 -04:00
Connor Turland 9b2193ad8c show autofollow on client and mute on unfollow 2017-09-03 15:18:57 -04:00
Connor Turland 1a8c7810be fix eslint issue picked up by codeclimate 2017-09-03 09:13:15 -04:00
Connor Turland d87bb7c75c make notifs and follows work for all users 2017-09-03 09:07:29 -04:00
Connor Turland aceb3ff31e Merge pull request #1129 from metamaps/feature/map.activity.improved
improve email styling for release
2017-09-03 08:33:13 -04:00
Connor Turland f26c6cf0b7 Merge pull request #1128 from metamaps/feature/prevent.notif.fork
dont send notification for each topic of forked map
2017-09-03 08:29:03 -04:00
Connor Turland 42f4ecb37b added bg color to sections 2017-09-03 08:27:05 -04:00
Connor Turland 64f4249f44 add comment 2017-09-02 14:12:07 -04:00
Connor Turland 958bd8c70c improve email styling for release 2017-09-02 14:06:23 -04:00
Connor Turland 3830946723 dont send notif for each topic of forked map 2017-09-02 09:59:21 -04:00
Connor Turland 3482e799fd Merge pull request #1127 from metamaps/update-docs
update docs
2017-07-26 09:26:59 -07:00
Connor Turland e016b923a4 Update WindowsInstallation.md 2017-07-26 09:25:41 -07:00
Connor Turland bb546779cd Update VagrantInstallation.md 2017-07-26 09:24:51 -07:00
Connor Turland 3829d32390 Update UbuntuInstallation.md 2017-07-26 09:22:34 -07:00
Connor Turland 9783a5ee1e Update MacInstallation.md 2017-07-26 09:22:06 -07:00
Connor Turland 12fc0c71f6 Update README.md 2017-07-26 09:21:16 -07:00
Connor Turland c2cb8949eb Create VagrantInstallation.md 2017-07-25 17:22:27 -07:00
Connor Turland 4e7bf02749 Update README.md 2017-07-25 17:19:17 -07:00
Connor Turland 3203c2b4d0 de-prioritize vagrant docs, as its no longer our setup of choice 2017-07-25 17:18:07 -07:00
Connor Turland 1ec9dc20e4 Update MacInstallation.md 2017-07-25 17:07:46 -07:00
Connor Turland 1af4728073 Update UbuntuInstallation.md 2017-07-25 17:06:27 -07:00
Connor Turland 785e16eeae make Vagrantfile realtime server port match default 2017-07-25 16:57:37 -07:00
Connor Turland d08cb3f95e Update UbuntuInstallation.md 2017-07-25 16:52:11 -07:00
Connor Turland 271fc7ebd0 Update MacInstallation.md 2017-07-25 16:47:33 -07:00
Connor Turland 9d590295cb Update WindowsInstallation.md 2017-07-25 16:44:40 -07:00
Connor Turland dc4d44951e Update UbuntuInstallation.md 2017-07-25 16:41:47 -07:00
Connor Turland 767414ad9f Update MacInstallation.md 2017-07-25 16:37:16 -07:00
Connor Turland 1ec897b8c8 Update MacInstallation.md 2017-07-17 20:45:34 -07:00
Connor Turland 00e2aefb4e Delete ISSUE_TEMPLATE.md 2017-07-16 20:50:14 -07:00
Connor Turland aec0f104b8 Merge pull request #1121 from JohnGillanders/develop
Update README.md
2017-07-09 23:32:41 -07:00
John Gillanders db6d2e77da Merge pull request #1 from metamaps/develop
Updates from metamaps base 04/07/2017
2017-07-04 12:59:20 +12:00
John Gillanders 9585dce511 Update README.md
Added example of cloning repository using https:// protocol instead of SSH protocol - this is simpler to do since no set-up of SSH keys is required.
2017-07-04 12:49:28 +12:00
Devin Howard 78acd7e0b0 fix NoMethodError in mappings after_created when synapse's topic1/topic2 are nil 2017-05-20 10:58:06 -07:00
Devin Howard 328c1a14f3 mark v3.4.1 one commit too late 2017-05-13 19:32:51 -07:00
Devin Howard 10ac64c574 before destroy callback on maps to remove source_id foreign key relations (#1119) 2017-05-13 19:26:43 -07:00
Devin Howard edce66c44d new react tests with enzyme library (#1116)
* move ImportDialogBox into a folder

* install enzyme

* start testing InfoAndHelp component

* add star logic to tests

* switch ImportDialogBox to using enzyme but tests are still failing

* make `npm run test` work

* tests pass again

* eslint

* try to fix travis by adding react-addons-test-utils again

* eslintrc for test dir

* remove duplicated code

* fix

* try to suppress 2 warnings
2017-05-13 13:50:52 -04:00
Devin Howard 74df2559a4 try to fix fatal on notifications index when a topic is invalid (#1115)
* try to fix fatal on notifications index when a topic is invalid

* Update index.html.erb
2017-05-13 13:49:46 -04:00
Robert Best a6694a3f72 Improvements to Import (#1109)
* Changed URL Regex to make more links importable, also removed need for special text formatting in order to paste or drop new topic labels. (Didn't break TSV import mode)

* Removed console logs

* add url regex with full documentation

* don't eslint 3rd party lib

* check for TSV only at start of string

* fix a bug with event/e and eslint

* handleTEXT => handleText
2017-04-11 11:51:22 -04:00
Devin Howard 8c7a657499 update vimeo url, use asset path + erb for poster path (#1106) 2017-03-26 13:53:59 -07:00
Connor Turland 90f77cd4f7 simplify views/topiccard (#1102)
* simplify views/topiccard

* Update Links.js
2017-03-22 19:22:38 -04:00
Connor Turland af4dc869c0 devins right shouldnt push straight to develop 2017-03-22 17:04:18 +00:00
Connor Turland 2cae12e1ab found a better way to handle junto chat panel 2017-03-22 16:35:28 +00:00
Connor Turland 49102ea474 only toggle if authorized 2017-03-22 16:13:59 +00:00
Connor Turland f2a7cc1f19 stop using jquery ui for topic card dragging 2017-03-22 16:10:08 +00:00
Devin Howard a5d5cd6000 fix editing synapse desc (#1101) 2017-03-20 19:32:54 -07:00
Devin Howard 391a1d8b24 link feedback directly to a hylo feedback tag (#1099) 2017-03-20 12:48:30 -07:00
Connor Turland cc17c1ed38 add tiny divider between global and map items 2017-03-17 12:54:18 -04:00
Connor Turland eee1febbf9 clean up unused vars and logs 2017-03-17 10:25:08 -04:00
Connor Turland c8f6374ac8 remove no longer needed comments 2017-03-17 09:32:52 -04:00
Connor Turland ed76162b63 added icons to mobile menu fixes #1095 2017-03-17 01:32:01 -04:00
Connor Turland 1eb4187691 broken import 2017-03-17 00:11:57 -04:00
Connor Turland 4a7dd54aca remove unused vars 2017-03-17 00:48:28 +00:00
Connor Turland efd6258c7e mobile.js was already removed but not deleted 2017-03-17 00:29:24 +00:00
Connor Turland f4d1b8ba35 ensure node is defined before calling function on it 2017-03-17 00:10:32 +00:00
Connor Turland 47a74dd77b react-router and rebuild app structure in react (#1091)
* initial restructuring

* stuff

* lock version number

* just keep using current mapinfobox

* fix map upperRightUI layout

* make mapsWidth work and add mobile

* remove filterBoxOpen for now

* redo the mobile menu in react

* get account menu and invite lightbox working

* fixed maps scrolling

* make other routes work

* fix signed out home page

* fix accountbox toggling

* add metacode edit routes

* lots of fixes

* fix map chat layout and tab bug

* improve topic card readability and fix dragging bug

* fixup mapchat stuff

* fix up navigation to use react-router

* jquery no longer handling access requests

* handle case where user hasn't loaded yet

* this shouldn't have been removed

* add frame for topic view

* rewrite map instructions

* fix toast (and sign out bug)

* fix apps pages and missing routes

* made our request invite page look nice

* filter box in react

* forgot to add one proptype

* remove extra comments

* handle page title and mobile title updates

* reenable google analytics

* make filterbox use onclickoutside

* reenable topic view in react

* fix csrf auth token

* fix little homepage styling issue

* try putting preparevizdata in a timeout

* installing render log to count

* little fixes

* fixup filters

* make filter map function names more readable

* eslint helps

* renaming for clarity

* use onclickoutside for account/sign in box

* add some logging to see whether this is source of many renders

* turns out chatview was heavily hogging memory

* tiimeout not needed
2017-03-16 17:58:56 -04:00
Robert Best 33276444c7 [Feature] Expand current selection to include neighbors by pressing CTRL+SHIFT+UP (#1090)
* Expand current selection to include neighbors by pressing CTRL+SHIFT+UP

* minor fixes as requested
2017-03-10 15:22:30 -08:00
Devin Howard 1124d76475 re-enable codeclimate duplication 2017-03-10 08:30:01 -08:00
Connor Turland 4ffa9460f5 bug fix for people who aren't testers on settings page 2017-03-10 11:29:00 -05:00
Connor Turland 44753dbfe1 Merge branch 'develop' 2017-03-09 14:55:59 -05:00
Connor Turland 77f76b1b5a variable name fix and make is_tester method global for reuse in views 2017-03-09 14:36:24 -05:00
Devin Howard e544d6a6db refactor api and fix bugs (#1088)
* fix weird double-embed issue

* fix users/current api if not logged in

* turbocharge the api

* fix docs
2017-03-09 14:24:52 -05:00
Devin Howard 780e66632b fix react embedly (#1089) 2017-03-09 14:23:24 -05:00
Connor Turland de4f51bb5c fix permissions and don't send if has map open 2017-03-08 15:45:40 -05:00
Connor Turland 5d0da4c5f1 method was preventing certain follows from succeeding 2017-03-08 15:02:22 -05:00
Connor Turland 9079d1bffc check permissions prior to sending 2017-03-08 15:01:58 -05:00
Connor Turland 962881a35d Update follow_service.rb 2017-03-08 14:13:47 -05:00
Connor Turland 8483b62603 allow users to select follow settings 2017-03-08 18:50:56 +00:00
Devin Howard e3b4dac1e1 remove takeScreenshot button in favour of separate buttons in the map card and import/export dialogue (#1086) 2017-03-07 12:15:28 -05:00
Connor Turland 8998e3858c fixes bug where popups are happening 2017-03-07 16:55:15 +00:00
Devin Howard ce51eeca8c remove dedupe plugin 2017-03-07 07:54:25 -08:00
Connor Turland 3178f6e650 bump version number 2017-03-07 03:58:29 +00:00
Connor Turland 7ee96bf6c6 Into master: two finger pan/zoom, map and topic follows (for internal testing) on the UI, map activity emails (#1084)
* fix topic spec

* fix synapse/mapping spec

* brakeman csrf warning suppressed :|

* follows for maps in the ui for internal testing only still (#1072)

* follows for maps in the ui for testers

* require user for these actions

* match how map follow works

* include ability to unfollow from email

* fixup templates

* add unfollow_from_email to the policies

* Update _cheatsheet.html.erb

Clean up text, clarify, and bring in line with current functionality

* topicsRegex and synapsesRegex should allow commas (#1073)

* even better import csv regexes

* prevent double prompt on file drop import

* topic card in react (#1031)

* its coming along

* links bar

* scssify a bunch

* metacode image working a bit better

* metacode selector in react topic card

* riek editing for name field on topic card

* riek submit on enter

* factor out Title and Links from Topic Card component, but not the listeners

* create working Desc editor

* styling is much better now

* textarea min height for desc

* disallow images in topic card markdown

* shift enter is linebreak, enter is save

* attachments split out, but it's pretty buggy

* move listeners into Links.js

* slightly wider metacodeTitle

* fix positioning on metacode selector

* fix metacode selection

* move metacode and permissions into subcomponents

* fixes

* prevent editing on desc/title if not authorized to edit

* fix topic card draggability

* fix embedly

* fix md test

* remove the removed link card manually with jquery

* fix test syntax

* eslint

* more eslin

* reuse authorizedToEdit

* convert metacode sets to a json object for react

* add the html in react whoop

* fix metacode styling

* sort wasn't working

* finishing metacode select

* readd the above link input border

* fix syntax

* multiline title editable textarea

* more portable metacode selector component

* factor out #metacodeOptions into one react component with a callback :D:D:D

* render metacodeOptions in right click menu with react

* render metacodeOptions in right click menu with react

* fix up right click menu's metacode editing

* fix topic card title character counter

* ignore metamaps secret bundle in ag

* simplify Attachments props

* factor out embedly card into its own component; it seems to help

* link resetter

* fix edit icon on title in topic card

* move mapCount and synapseCount hover/click logic to react

* fix up the showMore control

* metacode selection tweaks

* tweak links bar spacing in topic card

* rubocop

* remove TODOs

* more badass permissions selector

* close permission selector when you click outside

* fix overeager metacode selector

* more modular attachments component

* fix bug in Desc.js

* fix right click styling

* permission changes are different than edit rights

* bad module ref

* ensure maxLength on topic titles

* hellz yeah (#1074)

* fix drop from two touches to one

* don't commit activity service

* ability to select/unselect all metacodes in custom set with keyboard shortcut (fix #390) (#1078)

* ability to select/unselect all metacodes in custom set with keyboard shortcut

* select all button

* nicer all/none buttons

* set up react testing (#1080)

* install mocha-webpack. also switch hark to npm version instead of github version

* well, mocha-webpack runs

* add jsdom for tests

* upgrade to webpack 2

* fix npm run test errors

* ImportDialogBox component tests

* Fixes bug where pressing delete key while editing text will suggest... (#1083)

* Fixes bug where pressing delete key while editing text will suggest the deletion of selected map entities

* Changed the DEL key to remove entities instead of delete them

* temporarily disable code climate duplication engine

* add topic following for internal testing

* daily map activity emails (#1081)

* data prepared, task setup

* add the basics of the email template

* cover granular permissions

* unfollow this map

* break out permissions tests better

* rename so test runs
2017-03-06 22:49:46 -05:00
Connor Turland b740fef8fe daily map activity emails (#1081)
* data prepared, task setup

* add the basics of the email template

* cover granular permissions

* unfollow this map

* break out permissions tests better

* rename so test runs
2017-03-06 22:42:22 -05:00
Connor Turland 55b031ccb7 add topic following for internal testing 2017-03-07 01:47:10 +00:00
Devin Howard 9df389060e temporarily disable code climate duplication engine 2017-03-06 09:29:36 -08:00
Robert Best 153cc38d1a Fixes bug where pressing delete key while editing text will suggest... (#1083)
* Fixes bug where pressing delete key while editing text will suggest the deletion of selected map entities

* Changed the DEL key to remove entities instead of delete them
2017-03-06 11:48:59 -05:00
Devin Howard 4ff9619837 set up react testing (#1080)
* install mocha-webpack. also switch hark to npm version instead of github version

* well, mocha-webpack runs

* add jsdom for tests

* upgrade to webpack 2

* fix npm run test errors

* ImportDialogBox component tests
2017-03-06 02:29:12 +08:00
Devin Howard a6c1c0c730 ability to select/unselect all metacodes in custom set with keyboard shortcut (fix #390) (#1078)
* ability to select/unselect all metacodes in custom set with keyboard shortcut

* select all button

* nicer all/none buttons
2017-03-04 11:51:51 -05:00
Connor Turland 529dec09a3 don't commit activity service 2017-03-02 04:38:33 +00:00
Connor Turland ddbaac513f fix drop from two touches to one 2017-03-02 04:35:13 +00:00
Connor Turland ba943b20f1 hellz yeah (#1074) 2017-02-27 17:06:56 -05:00
Connor Turland 4deb3f5ab9 topic card in react (#1031)
* its coming along

* links bar

* scssify a bunch

* metacode image working a bit better

* metacode selector in react topic card

* riek editing for name field on topic card

* riek submit on enter

* factor out Title and Links from Topic Card component, but not the listeners

* create working Desc editor

* styling is much better now

* textarea min height for desc

* disallow images in topic card markdown

* shift enter is linebreak, enter is save

* attachments split out, but it's pretty buggy

* move listeners into Links.js

* slightly wider metacodeTitle

* fix positioning on metacode selector

* fix metacode selection

* move metacode and permissions into subcomponents

* fixes

* prevent editing on desc/title if not authorized to edit

* fix topic card draggability

* fix embedly

* fix md test

* remove the removed link card manually with jquery

* fix test syntax

* eslint

* more eslin

* reuse authorizedToEdit

* convert metacode sets to a json object for react

* add the html in react whoop

* fix metacode styling

* sort wasn't working

* finishing metacode select

* readd the above link input border

* fix syntax

* multiline title editable textarea

* more portable metacode selector component

* factor out #metacodeOptions into one react component with a callback :D:D:D

* render metacodeOptions in right click menu with react

* render metacodeOptions in right click menu with react

* fix up right click menu's metacode editing

* fix topic card title character counter

* ignore metamaps secret bundle in ag

* simplify Attachments props

* factor out embedly card into its own component; it seems to help

* link resetter

* fix edit icon on title in topic card

* move mapCount and synapseCount hover/click logic to react

* fix up the showMore control

* metacode selection tweaks

* tweak links bar spacing in topic card

* rubocop

* remove TODOs

* more badass permissions selector

* close permission selector when you click outside

* fix overeager metacode selector

* more modular attachments component

* fix bug in Desc.js

* fix right click styling

* permission changes are different than edit rights

* bad module ref

* ensure maxLength on topic titles
2017-02-26 11:42:47 -05:00
Devin Howard 47d0faadf2 prevent double prompt on file drop import 2017-02-25 13:04:00 -08:00
Devin Howard 9800cc27c6 even better import csv regexes 2017-02-25 12:15:45 -08:00
Devin Howard 7840e09e5f topicsRegex and synapsesRegex should allow commas (#1073) 2017-02-25 12:05:56 -08:00
ben, bro 687b957737 Update _cheatsheet.html.erb
Clean up text, clarify, and bring in line with current functionality
2017-02-23 22:03:33 -08:00
Connor Turland 9ce989eba5 add unfollow_from_email to the policies 2017-02-16 14:01:22 +00:00
Connor Turland 2c85590d65 fixup templates 2017-02-16 13:55:19 +00:00
Connor Turland 2b34d84715 include ability to unfollow from email 2017-02-16 13:42:35 +00:00
Connor Turland 013e3c7f21 follows for maps in the ui for internal testing only still (#1072)
* follows for maps in the ui for testers

* require user for these actions

* match how map follow works
2017-02-15 23:01:53 -05:00
Devin Howard 8d771543d8 Merge branch 'fix/rspec' into develop 2017-02-12 15:29:40 -08:00
Devin Howard 50639e8a0a Merge branch 'develop' 2017-02-12 15:11:19 -08:00
Devin Howard 9d52aa9c74 tag v3.3 2017-02-12 15:09:08 -08:00
Devin Howard 545706e17a disable cookie based auth on the API - mostly (#1070) 2017-02-12 12:54:54 -05:00
Devin Howard 95901e17e8 fix travis (#1071)
* fix topic spec

* fix synapse/mapping spec

* brakeman csrf warning suppressed :|
2017-02-12 12:53:04 -05:00
Devin Howard 9dbbdf1150 brakeman csrf warning suppressed :| 2017-02-11 20:00:42 -08:00
Devin Howard 4ee4aeaad2 fix synapse/mapping spec 2017-02-11 19:56:07 -08:00
Devin Howard bfdce21a66 fix topic spec 2017-02-11 19:54:09 -08:00
Devin Howard 99b21be27b tag v3.2 2017-01-16 14:18:49 -05:00
Devin Howard 2c60d7335c Merge branch 'develop' (v3.2) 2017-01-16 11:21:02 -05:00
Devin Howard b07941834c v3.1 in initializers 2016-12-16 17:22:48 -05:00
Devin Howard b914065bb3 Merge branch 'develop'; tag v3.1 2016-12-16 17:17:24 -05:00
Devin Howard 00286fcc29 tag v3.0.4 2016-12-06 12:38:06 -05:00
401 changed files with 7628 additions and 4529 deletions

1
.agignore Normal file
View file

@ -0,0 +1 @@
app/assets/javascripts/metamaps.secret.bundle.js

View file

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

2
.gitignore vendored
View file

@ -15,6 +15,7 @@ app/assets/javascripts/webpacked
#secrets and config
.env
*.swp
# Ignore bundler config
.bundle
@ -22,6 +23,7 @@ app/assets/javascripts/webpacked
# Ignore all logfiles and tempfiles.
log/*.log
tmp
.tmp
coverage

View file

@ -12,7 +12,7 @@ Rails:
Enabled: true
Metrics/LineLength:
Max: 100
Max: 120
Metrics/AbcSize:
Max: 16
@ -22,3 +22,8 @@ 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

11
Gemfile
View file

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

View file

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

View file

@ -28,39 +28,19 @@ 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
## Installation for local use or development of Metamaps
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.
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.
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`
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]
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`
If you prefer to isolate your install in a virtual machine, you may find it simpler to setup using Vagrant:
- [Vagrant installation][vagrant-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]
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]
## Licensing information
@ -76,4 +56,7 @@ 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 Normal file → Executable file
View file

@ -1,5 +1,6 @@
#!/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
View file

@ -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: 5001, host: 5001
config.vm.network :forwarded_port, guest: 5000, host: 5000
config.vm.network 'private_network', ip: '10.0.1.11'
config.vm.synced_folder '.', '/vagrant', nfs: true

Binary file not shown.

Before

Width:  |  Height:  |  Size: 543 B

View file

@ -10,6 +10,9 @@ Metamaps.ServerData['topic_link_signifier.png'] = '<%= asset_path('topic_link_si
Metamaps.ServerData['synapse16.png'] = '<%= asset_path('synapse16.png') %>'
Metamaps.ServerData['sounds/MM_sounds.mp3'] = '<%= asset_path 'sounds/MM_sounds.mp3' %>'
Metamaps.ServerData['sounds/MM_sounds.ogg'] = '<%= asset_path 'sounds/MM_sounds.ogg' %>'
Metamaps.ServerData['exploremaps_sprite.png'] = '<%= asset_path 'exploremaps_sprite.png' %>'
Metamaps.ServerData['map_control_sprite.png'] = '<%= asset_path 'map_control_sprite.png' %>'
Metamaps.ServerData['user_sprite.png'] = '<%= asset_path 'user_sprite.png' %>'
Metamaps.ServerData.Metacodes = <%= Metacode.all.to_json.gsub(%r[(icon.*?)(\"},)], '\1?purple=stupid\2').html_safe %>
Metamaps.ServerData.REALTIME_SERVER = '<%= ENV['REALTIME_SERVER'] %>'
Metamaps.ServerData.RAILS_ENV = '<%= ENV['RAILS_ENV'] %>'

View file

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

View file

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

View file

@ -193,10 +193,6 @@ button.button.btn-no:hover {
display: block;
width: 830px;
}
.requestInvite {
display: block;
margin: -720px auto 0;
}
.new_session,
.new_user,
.edit_user,
@ -672,9 +668,21 @@ label {
position: relative;
/*overflow:hidden; */
}
.main.compressed {
width: calc(100% - 300px);
.compressed {
.upperRightUI {
right: 324px;
}
.upperRightMapButtons {
right: 434px;
}
.mapControls {
right: 324px;
}
.infoAndHelp {
right: 370px;
}
}
#infovis-canvas {
-webkit-touch-callout: none;
-webkit-user-select: none;
@ -775,9 +783,9 @@ label {
}
.sidebarAccountIcon img {
border-radius: 16px;
width: 32px;
}
.sidebarAccountBox {
display: none;
height: auto;
}
.authenticated .sidebarAccountBox {
@ -818,6 +826,7 @@ label {
font-size: 14px;
line-height: 14px;
color: #757575;
cursor: pointer;
}
.accountListItem:hover {
color: #424242;
@ -1039,7 +1048,6 @@ label[for="user_remember_me"] {
}
.sidebarFilterBox {
display:none;
width: 319px;
padding: 16px 0;
overflow-y: auto;
@ -1250,7 +1258,7 @@ h3.filterBox {
box-shadow: 0px 3px 3px rgba(0,0,0,0.12), 0 3px 3px rgba(0,0,0,0.24);
}
.rightclickmenu .rc-permission:hover > ul,
.rightclickmenu .rc-metacode:hover > ul,
.rightclickmenu .rc-metacode:hover #metacodeOptions > ul,
.rightclickmenu .rc-siblings:hover > ul {
display: block;
}
@ -1279,7 +1287,7 @@ h3.filterBox {
.rightclickmenu li.toPrivate .rc-perm-icon {
background-position: -24px 0;
}
.rightclickmenu .rc-metacode > ul > li,
.rightclickmenu .rc-metacode #metacodeOptions > ul > li,
.rightclickmenu .rc-siblings > ul > li {
padding: 6px 24px 6px 8px;
white-space: nowrap;
@ -1907,14 +1915,10 @@ 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;
@ -2311,6 +2315,9 @@ and it won't be important on password protected instances */
}
/* switch metacode set */
#switchMetacodes > p {
margin: 16px 0 16px 0;
}
#metacodeSwitchTabs {
width: 100%;
font-size: 17px;
@ -2318,28 +2325,43 @@ and it won't be important on password protected instances */
border: none;
background: none;
padding: 0;
}
#metacodeSwitchTabs .setDesc {
margin-bottom: 5px;
font-family: 'din-medium', helvetica, sans-serif;
color: #424242;
font-size: 14px;
text-align: justify;
padding-right: 16px;
}
#switchMetacodes > p {
margin: 16px 0 16px 0;
}
#metacodeSwitchTabs > ul {
width: 130px;
}
#metacodeSwitchTabs > ul li {
font-size: 14px;
text-transform: uppercase;
}
#metacodeSwitchTabs li.ui-state-active a {
color: #00BCD4;
cursor: pointer;
.setDesc,
.selectAll,
.selectNone {
margin-bottom: 5px;
font-family: 'din-medium', helvetica, sans-serif;
color: #424242;
font-size: 14px;
text-align: justify;
padding-right: 16px;
display: inline-block;
}
.selectAll,
.selectNone {
float: right;
cursor: pointer;
&:hover,
&.selected {
color: #00bcd4;
}
}
& > ul {
width: 130px;
li {
font-size: 14px;
text-transform: uppercase;
}
}
li.ui-state-active a {
color: #00BCD4;
cursor: pointer;
}
}
.metacodeSwitchTab {
max-height: 300px;
@ -2908,146 +2930,18 @@ 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 */
#wrapper .requestInvite {
.requestInvite {
width: 700px;
margin: 0 auto;
padding: 0 0 60px 0;
background: #FFFFFF;
color: white;
height: 100%;
overflow: hidden;
height: calc(100% - 52px);
z-index: 1;
position: relative;
left: 50%;
margin-left: -350px;
margin-top: 52px;
}
.home_bg {
@ -3121,3 +3015,17 @@ script.data-gratipay-username {
.inline {
display: inline-block;
}
.topicFollow {
height: 24px;
line-height: 24px;
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;
}

View file

@ -1,11 +1,19 @@
$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;
font-family: helvetica, sans-serif;
color: #727272;
line-height: 11px;
display: none;
}
.riek-editing + .nameCounter {
display: block;
}
.nameCounter.forMap {
@ -14,21 +22,20 @@
}
.nameCounter.forTopic {
}
#center-container {
position:relative;
height:100%;
width:100%;
/* background-color:#031924; */
color:#444;
}
.showcard {
position:absolute;
display:none;
top:100px;
left:100px;
width:300px;
@ -38,7 +45,7 @@
z-index:2;
color: #424242;
border-radius:2px;
box-shadow: 0px 3px 3px rgba(0,0,0,0.23), 0 3px 3px rgba(0,0,0,0.16);
box-shadow: 2px 3px 3px rgba(125, 125, 125, 0.23), -2px -1px 3px rgba(125, 125, 125, 0.16);
}
.text {
@ -49,7 +56,6 @@
width:100%;
height:100%;
position: absolute;
display: none;
}
.showcard .permission {
@ -61,7 +67,6 @@
display:block;
position:relative;
width:100%;
min-height:360px;
z-index: 25;
}
.CardOnGraph.hasAttachment {
@ -70,11 +75,10 @@
.CardOnGraph .title {
word-break: break-word;
font-size: 18px;
line-height: 22px;
font-size: 20px;
line-height: 24px;
display: table;
padding: 8px 0 16px;
height: 80px;
padding: 20px 0;
text-align: center;
font-family: 'din-regular', sans-serif;
width: 300px;
@ -93,12 +97,11 @@
cursor: text;
}
.showcard .best_in_place_name textarea, .showcard .best_in_place_name input {
.showcard .title .riek-editing {
font-family: 'din-regular', sans-serif;
color: #424242;
font-size: 18px;
line-height: 22px;
height: 15px;
font-size: 20px;
line-height: 24px;
padding: 5px 0;
width: 100%;
margin: 0;
@ -112,30 +115,40 @@
.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;
}
.CardOnGraph .best_in_place_desc textarea {
.CardOnGraph .desc .riek-editing {
font-size: 13px;
line-height:15px;
font-family: helvetica, sans-serif;
color: #424242;
padding: 0;
width: 100%;
width: 258px;
margin: 0;
border: 0;
outline: none;
font-size: 12px;
line-height: 15px;
background: none;
resize: none;
overflow-y: scroll;
}
/*
@ -167,13 +180,11 @@
* End Markdown styling
*/
.CardOnGraph .best_in_place_desc {
.CardOnGraph .riek_desc {
display:block;
margin-top:2px;
padding-right: 18px;
margin-right: 8px;
padding-right: 26px;
}
.canEdit .CardOnGraph .best_in_place_desc:hover {
.canEdit .CardOnGraph .riek_desc:not(.riek-editing):hover {
background-image: url(<%= asset_data_uri('edit.png') %>);
background-position: top right;
background-repeat: no-repeat;
@ -185,155 +196,215 @@
}
.CardOnGraph .links {
position:relative;
border-bottom: 1px solid #BDBDBD;
border-top: 1px solid #BDBDBD;
background-color: #e0e0e0;
}
.linkItem {
float:left;
height:46px;
z-index: 1;
position: relative;
color: #424242;
font-size: 14px;
line-height:14px;
height:12px;
padding:17px 0;
}
.linkItem a {
color: #424242;
z-index: 2;
.linkItem {
float: left;
z-index: 1;
position: relative;
color: #424242;
font-size: 14px;
line-height: 14px;
a {
color: #424242;
}
}
.icon {
padding: 0;
height: 48px;
margin-right: 10px;
.metacodeImage {
cursor: move;
position: absolute;
left: -18px;
top: 6px;
width: 36px;
height: 36px;
background-size:36px 36px;
background-position:0 0;
background-repeat:no-repeat;
}
}
}
.CardOnGraph .icon {
position:absolute;
width:100%;
z-index:1;
padding: 0;
height: 48px;
}
.linkItem.contributor {
margin-left:40px;
z-index:1;
padding:17px 16px 17px 30px;
.CardOnGraph .info {
position: relative;
}
.contributor .contributorIcon {
position: absolute;
top: 8px;
left: 0;
border-radius: 16px;
}
.contributor:hover .contributorName {
display: block;
}
.linkItem {
float: left;
z-index: 1;
position: relative;
color: $mid-gray-opacity;
font-size: 14px;
line-height: 14px;
.contributorName {
display: none;
position: absolute;
background: black;
text-align: center;
color: white;
border-radius: 2px;
font-family: din-regular;
line-height: 15px;
font-size: 12px;
padding: 3px 5px 2px;
white-space: nowrap;
margin-top: 36px;
margin-left: -32px;
}
a {
color: $mid-gray-opacity;
}
}
.contributor div:before {
content: '';
position: absolute;
top: 128%;
left: 13px;
margin-top: -30px;
width: 0;
height: 0;
border-bottom: 4px solid #000000;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
}
.contributor {
bottom: 7px;
margin-left: 16px;
.linkItem.mapCount {
margin-left: 12px;
width: 24px;
padding:17px 0 17px 36px;
}
.linkItem.mapCount .mapCountIcon {
position: absolute;
top: 8px;
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;
}
.linkItem.mapCount:hover .mapCountIcon {
background-position: 0 -32px;
}
.contributorIcon {
position: relative;
display: inline-block;
vertical-align: middle;
border-radius: 16px;
margin: 5px 5px 5px 0;
top: 11px;
left: 0;
}
.linkItem.mapCount:hover .hoverTip {
display: block;
}
.CardOnGraph .mapCount .tip, .CardonGraph .mapCount .hoverTip {
top: 44px;
left: 0px;
font-size: 12px !important;
}
span {
font-family: 'din-regular', sans-serif;
font-size: 14px;
}
.hoverTip {
white-space: nowrap;
font-family: 'din-regular';
top: 44px;
left: 0px;
font-size: 12px !important;
display: none;
position: absolute;
background: black;
color: white;
border-radius: 4px;
line-height: 17px;
padding: 3px 5px 2px;
z-index: 100;
}
.contributorName {
font-family: din-regular;
margin-top: 20px;
display: inline-block;
vertical-align: middle;
width: 97px;
padding: 0 8px 0 4px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
}
.mapCount {
padding:17px 38px 17px 0;
width: 22px;
text-align: right;
.CardOnGraph .mapCount .tip:before, .CardOnGraph .mapCount .hoverTip: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;
}
.mapCountIcon {
position: absolute;
top: 8px;
right: 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;
}
.CardOnGraph .mapCount .tip li {
list-style-type: none;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: 6px 10px;
display: block;
height: 14px;
font-family: 'din-regular', helvetica, sans-serif;
font-size: 14px;
line-height: 14px;
position: relative;
}
&:hover .mapCountIcon {
background-position: 0 -32px;
}
.CardOnGraph .mapCount li.hideExtra {
display: none;
.tip, .hoverTip {
top: 44px;
right: 0px;
font-size: 12px !important;
&:before {
content: '';
position: absolute;
top: 26px;
right: 10px;
margin-top: -30px;
width: 0;
height: 0;
border-bottom: 4px solid $mid-gray;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
}
}
.hoverTip {
white-space: nowrap;
font-family: 'din-regular';
top: 44px;
font-size: 12px !important;
position: absolute;
background: $mid-gray;
color: white;
border-radius: 4px;
line-height: 17px;
padding: 3px 5px 2px;
z-index: 100;
}
.tip a {
color: white;
}
.tip a:hover {
color: #757575;
}
.tip li {
list-style-type: none;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
padding: 6px 10px;
display: block;
height: 14px;
font-family: 'din-regular', helvetica, sans-serif;
font-size: 14px;
line-height: 14px;
position: relative;
}
}
.synapseCount {
width: 22px;
padding:17px 38px 17px 0;
text-align: right;
margin-right: 4px;
.synapseCountIcon {
position: absolute;
top: 8px;
right: 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;
width: auto;
top: 44px;
right: 0px;
color: white;
white-space: nowrap;
border-radius: 2px;
font-size: 12px !important;
font-family: 'din-regular';
line-height: 12px;
padding: 4px 4px 4px;
z-index: 100;
}
.tip:before {
content: '';
position: absolute;
margin-top: -8px;
right: 12px;
width: 0;
height: 0;
border-bottom: 4px solid $mid-gray;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
}
}
}
.showMore {
@ -341,66 +412,10 @@
color: #4FC059;
}
.mapCount .tip a {
color: white;
.linkItem.mapPerm {
margin-right: 8px;
}
.mapCount .tip a:hover {
color: #757575;
}
.linkItem.synapseCount {
margin-left: 2px;
width: 24px;
padding:17px 0 17px 32px;
}
.linkItem.synapseCount .synapseCountIcon {
position: absolute;
top: 8px;
left: 0;
width: 32px;
height: 32px;
background-image: url(<%= asset_data_uri('synapse32_sprite.png') %>);
background-repeat: no-repeat;
background-position: 0 0;
}
.linkItem.synapseCount:hover .synapseCountIcon {
background-position: 0 -32px;
}
.CardOnGraph .synapseCount .tip {
position: absolute;
background: black;
width: auto;
top: 44px;
color: white;
white-space: nowrap;
border-radius: 2px;
font-size: 12px !important;
font-family: 'din-regular';
line-height: 12px;
padding: 4px 4px 4px;
z-index: 100;
}
.CardOnGraph .synapseCount:hover .tip {
display: block;
}
.CardOnGraph .synapseCount .tip:before {
content: '';
position: absolute;
margin-top: -8px;
margin-left: 6px;
width: 0;
height: 0;
border-bottom: 4px solid black;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
}
.mapPerm {
width: 32px;
height: 32px;
@ -422,14 +437,10 @@
}
.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 {
background-image: url(<%= asset_data_uri('arrowperms_sprite.png') %>) !important;
background-position: 0 0;
cursor: pointer;
cursor: pointer;
}
.mapPerm .permissionSelect {
list-style: none;
@ -465,63 +476,55 @@ cursor: pointer;
}
.CardOnGraph .metacodeTitle {
font-style: italic;
font-family: 'vinyl';
text-transform: uppercase;
position: absolute;
font-family: 'din-regular';
line-height: 24px;
height:24px;
font-size: 24px;
display: none;
width: 90%;
padding: 13px 0 9px 10%;
background-color: #E0E0E0;
height: 26px;
font-size: 18px;
padding: 13px 24px 9px 24px;
color: #424242;
width: 120px;
max-width: 120px;
white-space: nowrap;
text-overflow: ellipsis;
overflow: hidden;
}
.permission.canEdit .metacodeTitle {
cursor:pointer;
}
.permission.canEdit .expandMetacodeSelect {
position: absolute;
top: 16px;
right: 16px;
position: relative;
top: 2px;
left: 4px;
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 {
}
.CardOnGraph .metacodeImage {
cursor:move;
width:46px;
height:46px;
position:absolute;
left:-23px;
top:0;
background-size:46px 46px;
background-position:0 0;
background-repeat:no-repeat;
.CardOnGraph .metacodeName {
display: inline-block;
}
#metacodeOptions {
display:none;
}
.CardOnGraph .metacodeSelect {
display:none;
width:auto;
z-index: 2;
position: absolute;
background: #EAEAEA;
left: 300px;
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);
}
.CardOnGraph .metacodeSelect ul {
position: relative;
position: relative;
line-height: 14px;
font-size: 14px;
font-family: helvetica, sans-serif;
@ -610,11 +613,10 @@ background-color: #E0E0E0;
display:block;
}
.CardOnGraph .tip {
display:none;
position: absolute;
background: black;
background: $mid-gray;
top: 35px;
left: 0;
right: 0;
color: white;
border-radius: 4px;
font-size:15px !important;
@ -623,26 +625,23 @@ background-color: #E0E0E0;
z-index:100;
}
#embedlyLink {
display: none;
}
#embedlyLinkLoader {
margin: 0 auto;
width: 28px;
}
.CardOnGraph .attachments {
border-top: 1px solid #BDBDBD;
.CardOnGraph .link-adder {
width:100%;
height:47px;
position: relative;
}
.attachments a {
.link-adder a {
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
display: block;
margin-left: 40px;
margin-left: 40px;
padding-top:9px;
font-size: 16px;
line-height: 16px;
@ -652,7 +651,7 @@ background-color: #E0E0E0;
display: inline-block;
width: 102px;
height: 12px;
text-align: left;
text-align: left;
padding: 18px 0 18px 48px;
font-size: 12px;
color: #9e9e9e;
@ -696,9 +695,9 @@ background-color: #E0E0E0;
}
#addLinkInput input{
padding: 9px 7px 9px 31px;
padding: 9px 27px 9px 31px;
height: 12px;
width: 198px;
width: 210px;
margin: 0 0 0 0;
border: none;
outline: none;
@ -752,7 +751,6 @@ font-family: 'din-regular', helvetica, sans-serif;
-moz-border-radius-bottomright: 8px;
-webkit-border-bottom-right-radius: 8px;
border-bottom-right-radius: 8px;
display: none;
margin: 8px;
}
@ -839,10 +837,10 @@ font-family: 'din-regular', helvetica, sans-serif;
line-height: 16px;
}
.canEdit #edit_synapse_desc:hover {
.canEdit span.titleWrapper:hover {
background-image: url(<%= asset_data_uri('edit.png') %>);
background-repeat: no-repeat;
background-position: 164px center;
background-position: 95% 95%;
cursor: text;
}
@ -950,11 +948,11 @@ font-family: 'din-regular', helvetica, sans-serif;
}
#edit_synapse_right {
background-image: url(<%= asset_data_uri('synapsedirectionright_sprite.png') %>);
right: 16px;
right: 16px;
}
#edit_synapse_left {
background-image: url(<%= asset_data_uri('synapsedirectionleft_sprite.png') %>);
right: 56px;
right: 56px;
}
#edit_synapse_left.checked, #edit_synapse_right.checked {
background-position: 0 -48px;

View file

@ -30,6 +30,7 @@
height: 100%;
box-sizing: border-box;
padding-top: 92px;
overflow-y: auto;
}
/*.animations {
@ -46,26 +47,9 @@
transition-timing-function: ease-in-out;
}*/
.mapElement {
display: none;
}
.mapPage .mapElement,
.topicPage .mapElement {
display: block;
}
.mapPage .mapElementHidden,
.topicPage .mapElement.mapInfoBox,
.topicPage .mapElement.importDialog {
display:none;
}
.topicPage .starMap {
display: none;
}
/* loading */
#loading {
display: none;
width: 28px;
height: 28px;
position: fixed;
@ -184,10 +168,14 @@
}
.upperRightMapButtons {
top: -42px; /* puts it just offscreen */
right: 138px;
padding-right: 7px;
border-right: 1px solid #747474;
}
.mapPage .upperRightMapButtons, .topicPage .upperRightMapButtons {
top: 0;
.unauthenticated .upperRightMapButtons {
right: 115px;
padding-right: 0;
border-right: none;
}
.upperRightIcon {
@ -197,13 +185,7 @@
background-repeat: no-repeat;
cursor: pointer;
}
.mapPage .mapElement .importDialog {
display: none;
background-position: 0 0;
}
.mapPage.canEditMap .mapElement .importDialog {
display: block;
}
.sidebarFilterIcon {
background-position: -32px 0;
}
@ -236,6 +218,14 @@
/* end upperRightUI */
/* map wrapper */
.mapWrapper {
position:absolute;
width: 100%;
height: 100%;
}
/* end map wrapper */
/* yield */
@ -356,22 +346,15 @@
/* infoAndHelp */
.mapPage .infoAndHelp, .topicPage .infoAndHelp {
right: 70px;
}
.mapPage .openCheatsheet .tooltipsAbove, .topicPage .openCheatsheet .tooltipsAbove {
.openCheatsheet .tooltipsAbove {
right: 1px;
left: auto;
}
.unauthenticated .homePage .infoAndHelp {
display:none;
}
.infoAndHelp {
position: absolute;
bottom: 20px;
right: 20px;
right: 70px;
z-index: 3;
width: auto;
font-style: italic;
@ -392,16 +375,12 @@
}
.mapInfoIcon {
position: relative;
top: 56px; /* puts it just offscreen */
background-image: url(<%= asset_path('mapinfo_sprite.png') %>);
background-repeat:no-repeat;
background-image: url(<%= asset_path('mapinfo_sprite.png') %>);
background-repeat:no-repeat;
}
.mapInfoIcon:hover {
background-position: 0 -32px;
}
.mapPage .mapInfoIcon {
top: 0;
}
.starMap {
background-image: url(<%= asset_path('starmap_sprite.png') %>);
@ -419,9 +398,6 @@
background-position: 0 0;
}
.unauthenticated .mapPage .starMap {
display: none;
}
/* end infoAndHelp */
@ -430,24 +406,17 @@
.mapControls {
position: absolute;
bottom: 24px;
right:-32px; /* puts it just offscreen */
right:24px;
width:32px;
z-index: 3;
}
.mapPage .mapControls, .topicPage .mapControls {
right: 24px;
}
.topicPage .zoomExtents {
display: none;
}
.mapControl {
width:32px;
height:32px;
background-color: #424242;
background-repeat: no-repeat;
background-position: 0 0;
background-repeat: no-repeat;
background-position: 0 0;
cursor:pointer;
}
@ -455,19 +424,6 @@
z-index: 4;
}
.takeScreenshot {
margin-bottom: 5px;
border-radius: 2px;
background-image: url(<%= asset_path 'screenshot_sprite.png' %>);
display: none;
}
.takeScreenshot:hover {
background-position: -32px 0;
}
.canEditMap .takeScreenshot {
display: block;
}
.zoomExtents {
margin-bottom:5px;
border-radius: 2px;
@ -478,7 +434,7 @@
background-position: -32px 0;
}
.zoomExtents:hover .tooltips, .zoomIn:hover .tooltips, .zoomOut:hover .tooltips, .takeScreenshot:hover .tooltips, .sidebarFilterIcon:hover .tooltipsUnder, .sidebarForkIcon:hover .tooltipsUnder, .notificationsIcon:hover .tooltipsUnder, .addMap:hover .tooltipsUnder, .authenticated .sidebarAccountIcon:hover .tooltipsUnder,
.zoomExtents:hover .tooltips, .zoomIn:hover .tooltips, .zoomOut:hover .tooltips, .sidebarFilterIcon:hover .tooltipsUnder, .sidebarForkIcon:hover .tooltipsUnder, .notificationsIcon:hover .tooltipsUnder, .addMap:hover .tooltipsUnder, .authenticated .sidebarAccountIcon:hover .tooltipsUnder,
.mapInfoIcon:hover .tooltipsAbove, .openCheatsheet:hover .tooltipsAbove, .chat-button:hover .tooltips, .importDialog:hover .tooltipsUnder, .starMap:hover .tooltipsAbove, .openMetacodeSwitcher:hover .tooltipsAbove, .pinCarousel:not(.isPinned):hover .tooltipsAbove.helpPin, .pinCarousel.isPinned:hover .tooltipsAbove.helpUnpin {
display: block;
}
@ -600,16 +556,12 @@
left: -8px;
}
.openCheatsheet .tooltipsAbove {
left: -4px;
}
.sidebarAccountIcon .tooltipsUnder {
margin-left: -12px;
margin-top: 40px;
}
.zoomExtents div::after, .zoomIn div::after, .zoomOut div::after, .takeScreenshot div:after, .chat-button div.tooltips::after {
.zoomExtents div::after, .zoomIn div::after, .zoomOut div::after, .chat-button div.tooltips::after {
content: '';
position: absolute;
top: 57%;
@ -684,8 +636,11 @@
/* explore maps */
#explore {
display: none;
#react-app {
position: absolute;
height: 100%;
width: 100%;
overflow-y: auto;
}
#exploreMaps {
@ -704,23 +659,28 @@
display: block;
}
.appsPage #exploreMapsHeader {
display: block;
.requestInviteHeader {
position: absolute;
width: 100%;
z-index:2;
background-color:#FAFAFA;
height: 52px;
box-shadow: 0px 3px 3px rgba(0,0,0,0.23), 0 3px 3px rgba(0,0,0,0.16);
}
#exploreMapsHeader {
#navBar {
position: absolute;
width: 100%;
}
.exploreMapsBar {
.navBarContainer {
z-index:2;
background-color:#FAFAFA;
height: 42px;
padding-top: 52px;
}
.exploreMapsMenu {
.navBarMenu {
display: block;
width: 100%;
height:42px;
@ -729,30 +689,29 @@
text-align: center;
}
.exploreMapsCenter {
.navBarCenter {
display: block;
}
.exploreMapsButton {
color: #757575;
.navBarButton {
color: #757575;
cursor: default;
font-weight: normal;
font-family: 'din-medium';
font-size: 14px;
height: 14px;
padding: 14px 8px 12px 40px;
border-bottom: 2px solid rgba(0,0,0,0);
padding: 0 8px;
border-bottom: 2px solid rgba(0,0,0,0);
display: inline-block;
cursor: pointer;
position:relative;
cursor: pointer;
position:relative;
}
.exploreMapsButton:hover, .exploreMapsButton.active {
.navBarButton:hover, .navBarButton.active {
text-decoration: none;
color: #424242;
border-bottom: 2px solid #00BCD4;
}
.exploreMapsButton.mapperButton {
.navBarButton.mapperButton {
height: 40px;
padding: 0;
}
@ -769,62 +728,69 @@
}
.exploreMapsButton .exploreMapsIcon {
.navBarButton .navBarIcon {
background-repeat: no-repeat;
width:32px;
height:32px;
position:absolute;
top:5px;
left:5px;
margin-top:5px;
margin-left:5px;
margin-right: 5px;
display: inline-block;
vertical-align: top;
}
.exploreMapsCenter .authedApps .exploreMapsIcon {
.navBarLinkText {
padding: 11px 0 12px 0;
display: inline-block;
}
.navBarCenter .authedApps .navBarIcon {
background-image: url(<%= asset_path('user_sprite.png') %>);
background-position: 0 -32px;
}
.exploreMapsCenter .myMaps .exploreMapsIcon {
.navBarCenter .myMaps .navBarIcon {
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
background-position: -32px 0;
}
.exploreMapsCenter .sharedMaps .exploreMapsIcon {
.navBarCenter .sharedMaps .navBarIcon {
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
background-position: -128px 0;
}
.exploreMapsCenter .activeMaps .exploreMapsIcon {
.navBarCenter .activeMaps .navBarIcon {
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
background-position: 0 0;
}
.exploreMapsCenter .featuredMaps .exploreMapsIcon {
.navBarCenter .featuredMaps .navBarIcon {
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
background-position: -96px 0;
}
.exploreMapsCenter .starredMaps .exploreMapsIcon {
.navBarCenter .starredMaps .navBarIcon {
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
background-position: -96px 0;
}
.exploreMapsCenter .notificationsLink .exploreMapsIcon {
.navBarCenter .notificationsLink .navBarIcon {
background-image: url(<%= asset_path 'topright_sprite.png' %>);
background-position: -128px 0;
}
.authedApps:hover .exploreMapsIcon, .authedApps.active .exploreMapsIcon {
.authedApps:hover .navBarIcon, .authedApps.active .navBarIcon {
background-position-x: -32px;
}
.myMaps:hover .exploreMapsIcon, .myMaps.active .exploreMapsIcon {
.myMaps:hover .navBarIcon, .myMaps.active .navBarIcon {
background-position: -32px -32px;
}
.activeMaps:hover .exploreMapsIcon, .activeMaps.active .exploreMapsIcon {
.activeMaps:hover .navBarIcon, .activeMaps.active .navBarIcon {
background-position: 0 -32px;
}
.featuredMaps:hover .exploreMapsIcon, .featuredMaps.active .exploreMapsIcon {
.featuredMaps:hover .navBarIcon, .featuredMaps.active .navBarIcon {
background-position: -96px -32px;
}
.starredMaps:hover .exploreMapsIcon, .starredMaps.active .exploreMapsIcon {
.starredMaps:hover .navBarIcon, .starredMaps.active .navBarIcon {
background-position: -96px -32px;
}
.sharedMaps:hover .exploreMapsIcon, .sharedMaps.active .exploreMapsIcon {
.sharedMaps:hover .navBarIcon, .sharedMaps.active .navBarIcon {
background-position: -128px -32px;
}
.notificationsLink:hover .exploreMapsIcon, .notificationsLink.active .exploreMapsIcon {
.notificationsLink:hover .navBarIcon, .notificationsLink.active .navBarIcon {
background-position-y: -32px;
}
@ -842,7 +808,6 @@
height: 80px;
font-family: 'din-regular', helvetica, sans-serif;
font-size: 32px;
display: none;
text-align: center;
color: #999999;
z-index: 0;
@ -858,7 +823,6 @@
/* toast */
.toast {
display: none;
position: fixed;
bottom: 20px;
left: 20px;

View file

@ -98,21 +98,21 @@
top: 72px;
}
#chat-box-wrapper {
height: 100%;
float: right;
}
.chat-box {
position: relative;
display: flex;
flex-direction: column;
position: absolute;
right: 0;
z-index: 1;
width: 300px;
height: 100%;
background: #424242;
box-shadow: -8px 0px 16px 2px rgba(0, 0, 0, 0.23);
.chat-panel {
width: 300px;
display: flex;
flex-direction: column;
height: 100%;
}
.chat-button {
position: absolute;
top: 50%;

View file

@ -1,7 +1,3 @@
#mobile_header {
display: none;
}
@media only screen and (max-width : 752px) and (min-width : 504px) {
.sidebarSearch .tt-hint, .sidebarSearch .sidebarSearchField {
width: 160px !important;
@ -36,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, #exploreMapsHeader {
.upperLeftUI, .upperRightUI, .openCheatsheet, .mapInfoIcon, .feedback-icon, .chat-box, #navBar {
display: none !important;
}
@ -51,10 +47,6 @@
display: none;
}
#mobile_header {
display: block;
}
.homeWrapper {
width: 96%;
padding: 0 2%;
@ -72,7 +64,7 @@
height: auto;
}
.homeVideo {
width: 100%;
width: 100% !important;
height: auto;
}
.fullWidthWrapper.withPartners {
@ -108,15 +100,23 @@
max-width: 360px;
}
#wrapper .requestInvite {
.requestInviteHeader {
display: none;
}
.requestInvite {
width: 100%;
padding: 0;
height: calc(100% - 50px);
z-index: 1;
position: relative;
left: 0;
margin-left: 0px;
margin-top: 50px;
}
#exploreMaps > div {
margin-top: 70px;
}
.mapper {
width: 100%;
margin: 0 0 30px 0;
@ -217,6 +217,7 @@
width: 100%;
box-shadow: 0px 3px 3px rgba(0,0,0,0.23), 0 3px 3px rgba(0,0,0,0.16);
position: fixed;
z-index: 1;
}
#menu_icon {
@ -249,7 +250,6 @@
}
#mobile_menu {
display: none;
background: #EEE;
position: fixed;
top: 50px;
@ -257,10 +257,19 @@
padding: 10px;
width: 200px;
box-shadow: 3px 3px 3px rgba(0,0,0,0.23), 3px 3px 3px rgba(0,0,0,0.16);
z-index: 2;
li {
padding: 10px;
padding: 7px 10px;
list-style: none;
font-family: 'din-regular', arial, sans-serif;
.sprite {
margin-right: 6px;
margin-top: -2px;
display: inline-block;
vertical-align: middle;
}
&.notifications {
position: relative;
@ -274,16 +283,6 @@
}
}
/*
* the mobile menu, even if it's been opened by a user, should
* not show up if they resize their browser back to full size
*/
@media only screen and (max-width : 504px) {
#mobile_menu.visible {
display: block;
}
}
li.mobileMenuUser {
border-bottom: 1px solid #BBB;
}

View file

@ -1,4 +1,7 @@
$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;
@ -13,13 +16,72 @@ $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;
@ -47,89 +109,9 @@ $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 {
@ -139,14 +121,14 @@ $unread_notifications_dot_size: 8px;
border-radius: 16px;
vertical-align: middle;
}
.button {
line-height: 32px;
img {
margin-top: 8px;
}
&.decline {
background: #DB5D5D;
&:hover {
@ -154,7 +136,7 @@ $unread_notifications_dot_size: 8px;
}
}
}
.notification-body {
p, div {
margin: 1em auto;
@ -163,3 +145,93 @@ $unread_notifications_dot_size: 8px;
}
}
}
ul.notifications {
list-style: none;
li:nth-last-child(2) {
.notification-body {
border-bottom: none !important;
}
}
}
.notification {
padding: 10px 10px 0 10px;
position: relative;
font-family: 'din-regular', Sans-Serif;
&.unread {
background: #EEE;
}
&:hover {
background: $notifications-hover-color;
.notification-read-unread {
display:block;
}
.notification-date {
display: none;
}
}
& > a {
float: left;
width: 85%;
box-sizing: border-box;
padding-right: 10px;
}
.notification-actor {
float: left;
img {
width: 32px;
height: 32px;
border-radius: 16px;
}
}
.notification-body {
margin-left: 50px;
line-height: 20px;
padding-bottom: 10px;
.in-bold {
font-family: 'din-medium', Sans-Serif;
}
.action {
background: #4fb5c0;
color: #FFF;
padding: 2px 6px;
border-radius: 3px;
display: inline-block;
margin: 5px 0;
}
}
.notification-date {
position: absolute;
top: 50%;
right: 10px;
color: #607d8b;
margin-top: -6px;
}
.notification-read-unread {
display: none;
float: left;
width: 15%;
a, div {
position: absolute;
top: 50%;
margin-top: -10px;
text-align: center;
cursor: pointer;
}
}
}

View file

@ -1,7 +1,6 @@
.viewOnly {
float: left;
margin-left: 16px;
display: none;
height: 32px;
border: 1px solid #BDBDBD;
border-radius: 2px;
@ -23,7 +22,7 @@
}
.requestNotice {
display: none;
display: inline-block;
padding: 0 8px;
}
@ -42,16 +41,6 @@
.requestNotAccepted {
background-color: #c04f4f;
}
&.sendRequest .requestAccess {
display: inline-block;
}
&.sentRequest .requestPending {
display: inline-block;
}
&.requestDenied .requestNotAccepted {
display: inline-block;
}
}
.request_access {

View file

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

View file

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

View file

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

View file

@ -1,11 +1,12 @@
# frozen_string_literal: true
class AccessController < ApplicationController
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]
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]
after_action :verify_authorized
# GET maps/:id/request_access

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,8 +1,10 @@
# frozen_string_literal: true
module Api
module V2
class UsersController < RestfulController
def current
raise Pundit::NotAuthorizedError if current_user.nil?
@user = current_user
authorize @user
show # delegate to the normal show function

View file

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

View file

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

View file

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

View file

@ -1,4 +1,5 @@
# 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

View file

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

View file

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

View file

@ -1,7 +1,10 @@
# frozen_string_literal: true
class MapsController < ApplicationController
before_action :require_user, only: [:create, :update, :destroy, :events]
before_action :set_map, only: [:show, :conversation, :update, :destroy, :contains, :events, :export]
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]
after_action :verify_authorized
# GET maps/:id
@ -23,7 +26,7 @@ class MapsController < ApplicationController
format.ttl { redirect_to action: :export, format: :ttl }
end
end
# GET maps/:id/conversation
def conversation
respond_to do |format|
@ -138,6 +141,43 @@ class MapsController < ApplicationController
end
end
# POST maps/:id/follow
def follow
follow = FollowService.follow(@map, current_user, 'followed')
respond_to do |format|
format.json do
if follow
head :ok
else
head :bad_request
end
end
end
end
# POST maps/:id/unfollow
def unfollow
FollowService.unfollow(@map, current_user)
respond_to do |format|
format.json do
head :ok
end
end
end
# GET maps/:id/unfollow_from_email
def unfollow_from_email
FollowService.unfollow(@map, current_user)
respond_to do |format|
format.html do
redirect_to map_path(@map), notice: 'You are no longer following this map'
end
end
end
private
def set_map

View file

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

View file

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

View file

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

View file

@ -1,18 +1,23 @@
# frozen_string_literal: true
class NotificationsController < ApplicationController
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]
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]
def index
@notifications = current_user.mailbox.notifications.page(params[:page]).per(25)
respond_to do |format|
format.html
format.json do
render json: @notifications.map do |notification|
notifications = @notifications.map do |notification|
receipt = @receipts.find_by(notification_id: notification.id)
notification.as_json.merge(is_read: receipt.is_read)
NotificationDecorator.decorate(notification, receipt)
end
if !notifications.empty?
render json: notifications
else
render json: [].to_json
end
end
end
@ -23,20 +28,18 @@ 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: @notification.as_json.merge(
is_read: @receipt.is_read
)
render json: NotificationDecorator.decorate(@notification, @receipt)
end
end
end
@ -46,9 +49,7 @@ class NotificationsController < ApplicationController
respond_to do |format|
format.js
format.json do
render json: @notification.as_json.merge(
is_read: @receipt.is_read
)
render json: NotificationDecorator.decorate(@notification, @receipt)
end
end
end
@ -58,9 +59,7 @@ class NotificationsController < ApplicationController
respond_to do |format|
format.js
format.json do
render json: @notification.as_json.merge(
is_read: @receipt.is_read
)
render json: NotificationDecorator.decorate(@notification, @receipt)
end
end
end

View file

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

View file

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

View file

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

View file

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

View file

@ -1,8 +1,12 @@
# frozen_string_literal: true
class TopicsController < ApplicationController
include TopicsHelper
before_action :require_user, only: [:create, :update, :destroy]
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]
after_action :verify_authorized, except: :autocomplete_topic
respond_to :html, :js, :json
@ -10,7 +14,7 @@ class TopicsController < ApplicationController
# GET /topics/autocomplete_topic
def autocomplete_topic
term = params[:term]
if term && !term.empty?
if term.present?
topics = policy_scope(Topic)
.where('LOWER("name") like ?', term.downcase + '%')
.order('"name"')
@ -31,9 +35,6 @@ class TopicsController < ApplicationController
# GET topics/:id
def show
@topic = Topic.find(params[:id])
authorize @topic
respond_to do |format|
format.html do
@alltopics = [@topic].concat(policy_scope(Topic.relatives(@topic.id, current_user)).to_a)
@ -49,9 +50,6 @@ class TopicsController < ApplicationController
# GET topics/:id/network
def network
@topic = Topic.find(params[:id])
authorize @topic
@alltopics = [@topic].concat(policy_scope(Topic.relatives(@topic.id, current_user)).to_a)
@allsynapses = policy_scope(Synapse.for_topic(@topic.id))
@ -71,9 +69,6 @@ class TopicsController < ApplicationController
# GET topics/:id/relative_numbers
def relative_numbers
@topic = Topic.find(params[:id])
authorize @topic
topics_already_has = params[:network] ? params[:network].split(',').map(&:to_i) : []
alltopics = policy_scope(Topic.relatives(@topic.id, current_user)).to_a
@ -94,9 +89,6 @@ class TopicsController < ApplicationController
# GET topics/:id/relatives
def relatives
@topic = Topic.find(params[:id])
authorize @topic
topics_already_has = params[:network] ? params[:network].split(',').map(&:to_i) : []
alltopics = policy_scope(Topic.relatives(@topic.id, current_user)).to_a
@ -149,8 +141,6 @@ class TopicsController < ApplicationController
# PUT /topics/1
# PUT /topics/1.json
def update
@topic = Topic.find(params[:id])
authorize @topic
@topic.updated_by = current_user
@topic.assign_attributes(topic_params)
@ -165,8 +155,6 @@ class TopicsController < ApplicationController
# DELETE topics/:id
def destroy
@topic = Topic.find(params[:id])
authorize @topic
@topic.updated_by = current_user
@topic.destroy
respond_to do |format|
@ -174,8 +162,50 @@ class TopicsController < ApplicationController
end
end
# POST topics/:id/follow
def follow
follow = FollowService.follow(@topic, current_user, 'followed')
respond_to do |format|
format.json do
if follow
head :ok
else
head :bad_request
end
end
end
end
# POST topics/:id/unfollow
def unfollow
FollowService.unfollow(@topic, current_user)
respond_to do |format|
format.json do
head :ok
end
end
end
# GET topics/:id/unfollow_from_email
def unfollow_from_email
FollowService.unfollow(@topic, current_user)
respond_to do |format|
format.html do
redirect_to topic_path(@topic), notice: 'You are no longer following this topic'
end
end
end
private
def set_topic
@topic = Topic.find(params[:id])
authorize @topic
end
def topic_params
params.require(:topic).permit(:id, :name, :desc, :link, :permission, :metacode_id, :defer_to_map_id)
end

View file

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

View file

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

View file

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

View file

@ -1,6 +1,7 @@
# frozen_string_literal: true
class UsersController < ApplicationController
before_action :require_user, only: [:edit, :update, :updatemetacodes, :update_metacode_focus]
before_action :require_user, only: %i[edit update updatemetacodes update_metacode_focus]
respond_to :html, :json
@ -23,14 +24,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])
@user.image = nil if params[:remove_image] == '1'
@user.save
sign_in(@user, bypass: true)
bypass_sign_in(@user)
respond_to do |format|
format.html { redirect_to root_url, notice: 'Account updated!' }
format.html { redirect_to root_url, notice: 'Settings updated' }
end
else
sign_in(@user, bypass: true)
bypass_sign_in(@user)
respond_to do |format|
format.html { redirect_to edit_user_path(@user), notice: @user.errors.to_a[0] }
end
@ -40,11 +42,12 @@ 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])
@user.image = nil if params[:remove_image] == '1'
@user.save
sign_in(@user, bypass: true)
respond_to do |format|
format.html { redirect_to root_url, notice: 'Account updated!' }
format.html { redirect_to root_url, notice: 'Settings updated' }
end
else
respond_to do |format|
@ -98,15 +101,22 @@ 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
private
def update_follow_settings(user, settings)
user.settings.follow_topic_on_created = settings[:follow_topic_on_created]
user.settings.follow_topic_on_contributed = settings[:follow_topic_on_contributed]
user.settings.follow_map_on_created = settings[:follow_map_on_created]
user.settings.follow_map_on_contributed = settings[:follow_map_on_contributed]
end
def user_params
params.require(:user).permit(
:name, :email, :image, :password, :password_confirmation, :emails_allowed
:name, :email, :image, :password, :password_confirmation, :emails_allowed, :settings
)
end
end

View file

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

View file

@ -1,55 +1,6 @@
# frozen_string_literal: true
module ApplicationHelper
def metacodeset
metacodes = current_user.settings.metacodes
return false unless metacodes[0].include?('metacodeset')
return 'Most' if metacodes[0].sub('metacodeset-', '') == 'Most'
return 'Recent' if metacodes[0].sub('metacodeset-', '') == 'Recent'
MetacodeSet.find(metacodes[0].sub('metacodeset-', '').to_i)
end
def user_metacodes
@m = current_user.settings.metacodes
set = metacodeset
@metacodes = if set && set == 'Most'
Metacode.where(id: current_user.most_used_metacodes).to_a
elsif set && set == 'Recent'
Metacode.where(id: current_user.recent_metacodes).to_a
elsif set
set.metacodes.to_a
else
Metacode.where(id: @m).to_a
end
focus_code = user_metacode()
if focus_code != nil && @metacodes.index{|m| m.id == focus_code.id} == nil
@metacodes.push(focus_code)
end
@metacodes
.sort! { |m1, m2| m2.name.downcase <=> m1.name.downcase }
if focus_code != nil
@metacodes.rotate!(@metacodes.index{|m| m.id == focus_code.id})
else
@metacodes.rotate!(-1)
end
end
def user_metacode
current_user.settings.metacode_focus ? Metacode.find(current_user.settings.metacode_focus.to_i) : nil
end
def user_most_used_metacodes
@metacodes = current_user.most_used_metacodes.map { |id| Metacode.find(id) }
end
def user_recent_metacodes
@metacodes = current_user.recent_metacodes.map { |id| Metacode.find(id) }
end
def invite_link
"#{request.base_url}/join" + (current_user ? "?code=#{current_user.code}" : '')
end

View file

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

View file

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

View file

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

View file

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

View file

@ -1,3 +1,5 @@
# frozen_string_literal: true
module MapMailerHelper
def access_approved_subject(map)
map.name + ' - access approved'
@ -5,9 +7,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

View file

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

View file

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

View file

@ -1,3 +0,0 @@
# frozen_string_literal: true
module MetacodeSetsHelper
end

View file

@ -1,3 +1,79 @@
# frozen_string_literal: true
module MetacodesHelper
def metacodeset
metacodes = current_user.settings.metacodes
return false unless metacodes[0].include?('metacodeset')
return 'Most' if metacodes[0].sub('metacodeset-', '') == 'Most'
return 'Recent' if metacodes[0].sub('metacodeset-', '') == 'Recent'
MetacodeSet.find(metacodes[0].sub('metacodeset-', '').to_i)
end
def user_metacodes
@m = current_user.settings.metacodes
set = metacodeset
@metacodes = if set && set == 'Most'
Metacode.where(id: current_user.most_used_metacodes).to_a
elsif set && set == 'Recent'
Metacode.where(id: current_user.recent_metacodes).to_a
elsif set
set.metacodes.to_a
else
Metacode.where(id: @m).to_a
end
focus_code = user_metacode
if !focus_code.nil? && @metacodes.index { |m| m.id == focus_code.id }.nil?
@metacodes.push(focus_code)
end
@metacodes.sort! { |m1, m2| m2.name.downcase <=> m1.name.downcase }
if !focus_code.nil?
@metacodes.rotate!(@metacodes.index { |m| m.id == focus_code.id })
else
@metacodes.rotate!(-1)
end
end
def user_metacode
current_user.settings.metacode_focus ? Metacode.find(current_user.settings.metacode_focus.to_i) : nil
end
def user_most_used_metacodes
@metacodes = current_user.most_used_metacodes.map { |id| Metacode.find(id) }
end
def user_recent_metacodes
@metacodes = current_user.recent_metacodes.map { |id| Metacode.find(id) }
end
def metacode_sets_json
metacode_sets = []
metacode_sets << {
name: 'Recently Used',
metacodes: user_recent_metacodes
.map { |m| { id: m.id, icon_path: asset_path(m.icon), name: m.name } }
}
metacode_sets << {
name: 'Most Used',
metacodes: user_most_used_metacodes
.map { |m| { id: m.id, icon_path: asset_path(m.icon), name: m.name } }
}
metacode_sets += MetacodeSet.order('name').all.map do |set|
{
name: set.name,
metacodes: set.metacodes.order('name')
.map { |m| { id: m.id, icon_path: asset_path(m.icon), name: m.name } }
}
end
metacode_sets << {
name: 'All',
metacodes: Metacode.order('name').all
.map { |m| { id: m.id, icon_path: asset_path(m.icon), name: m.name } }
}
metacode_sets.to_json
end
end

View file

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

View file

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

View file

@ -1,4 +1,5 @@
# frozen_string_literal: true
module TopicsHelper
## this one is for building our custom JSON autocomplete format for typeahead
def autocomplete_array_json(topics)
@ -16,7 +17,7 @@ module TopicsHelper
rtype: is_map ? 'map' : 'topic',
inmaps: is_map ? [] : t.inmaps(current_user),
inmapsLinks: is_map ? [] : t.inmapsLinks(current_user),
inmapsLinks: is_map ? [] : t.inmaps_links(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,

View file

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

View file

@ -1,33 +1,30 @@
# frozen_string_literal: true
class ApplicationMailer < ActionMailer::Base
default from: 'team@metamaps.cc'
layout 'mailer'
def deliver
raise NotImplementedError('Please use Mailboxer to send your emails.')
end
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

View file

@ -0,0 +1,12 @@
# frozen_string_literal: true
class MapActivityMailer < ApplicationMailer
default from: 'team@metamaps.cc'
def daily_summary(user, map, summary_data)
@user = user
@map = map
@summary_data = summary_data
mail(to: user.email, subject: MapActivityService.subject_line(map))
end
end

View file

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

View file

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

View file

@ -1,9 +1,10 @@
# frozen_string_literal: true
class AccessRequest < ApplicationRecord
belongs_to :user
belongs_to :map
has_one :user_map
after_create :after_created_async
def approve
@ -27,9 +28,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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,16 +1,17 @@
# 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

View file

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

View file

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

View file

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

View file

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

View file

@ -1,4 +1,5 @@
# frozen_string_literal: true
module Events
class TopicAddedToMap < Event
after_create :notify_users!
@ -10,7 +11,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)

View file

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

View file

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

View file

@ -1,7 +1,8 @@
# 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',
@ -9,7 +10,7 @@ module Events
user: user,
meta: meta)
end
def notify_users!
NotificationService.notify_followers(eventable, 'topic_updated', self)
end

View file

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

View file

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

View file

@ -1,19 +1,21 @@
# frozen_string_literal: true
class Follow < ApplicationRecord
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
follow_reason = FollowReason.create!(follow: self)
FollowReason.create!(follow: self)
end
end

View file

@ -1,12 +1,13 @@
# 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

View file

@ -1,4 +1,5 @@
# 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'

View file

@ -1,6 +1,7 @@
# 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
@ -15,7 +16,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
@ -39,9 +40,10 @@ class Map < ApplicationRecord
# Validate the attached image is image/jpg, image/png, etc
validates_attachment_content_type :screenshot, content_type: %r{\Aimage/.*\Z}
after_create :after_created_async
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
@ -88,10 +90,10 @@ class Map < ApplicationRecord
def as_json(_options = {})
json = super(
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]
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]
)
json[:created_at_clean] = created_at_str
json[:updated_at_clean] = updated_at_str
@ -132,31 +134,35 @@ 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_async
FollowService.follow(self, self.user, 'created')
def after_created
FollowService.follow(self, user, 'created')
# notify users following the map creator
end
handle_asynchronously :after_created_async
def after_updated
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
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
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)
end
end
end

View file

@ -1,7 +1,8 @@
# 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
@ -24,7 +25,7 @@ class Mapping < ApplicationRecord
end
def as_json(_options = {})
super(methods: [:user_name, :user_image])
super(methods: %i[user_name user_image])
end
def after_created
@ -37,31 +38,32 @@ 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
)
Events::SynapseAddedToMap.publish!(mappable, map, user, nil)
meta = { 'mapping_id': id }
Events::SynapseAddedToMap.publish!(mappable, map, user, meta)
end
end
def after_created_async
FollowService.follow(map, user, 'contributed')
end
handle_asynchronously :after_created_async
def after_updated
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
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)
end
def after_updated_async
if (mappable_type == 'Topic') && (xloc_changed? || yloc_changed?)
FollowService.follow(map, updated_by, 'contributed')
end
return unless (mappable_type == 'Topic') && (xloc_changed? || yloc_changed?)
FollowService.follow(map, updated_by, 'contributed')
end
handle_asynchronously :after_updated_async

View file

@ -1,4 +1,5 @@
# frozen_string_literal: true
class Message < ApplicationRecord
belongs_to :user
belongs_to :resource, polymorphic: true
@ -6,22 +7,21 @@ 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: [:user_name, :user_image])
json = super(methods: %i[user_name user_image])
json
end
def after_created
ActionCable.server.broadcast 'map_' + resource.id.to_s, type: 'messageCreated', message: as_json
end
def after_created_async
FollowService.follow(resource, user, 'commented')
NotificationService.notify_followers(resource, 'map_message', self)

View file

@ -1,17 +1,16 @@
# 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: /\Aimage\/.*\Z/
validates_attachment_content_type :aws_icon, content_type: %r{\Aimage/.*\Z}
validate :aws_xor_manual_icon
validate :manual_icon_https
@ -30,15 +29,13 @@ 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 hasSelected(user)
return true if user.settings.metacodes.include? id.to_s
false
end
def inMetacodeSet(metacode_set)
def in_metacode_set(metacode_set)
return true if metacode_sets.include? metacode_set
false
end
@ -55,10 +52,9 @@ class Metacode < ApplicationRecord
end
def manual_icon_https
if manual_icon.present?
unless manual_icon.starts_with? 'https'
errors.add(:base, 'Manual icon must begin with https')
end
return if manual_icon.blank?
unless manual_icon.starts_with? 'https'
errors.add(:base, 'Manual icon must begin with https')
end
end
end

View file

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

View file

@ -1,13 +1,18 @@
# frozen_string_literal: true
class PermittedParams < Struct.new(:params)
%w(map synapse topic mapping token).each do |kind|
class PermittedParams
%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
@ -15,18 +20,18 @@ class PermittedParams < Struct.new(:params)
end
def map_attributes
[:name, :desc, :permission, :arranged]
%i[name desc permission arranged]
end
def synapse_attributes
[:desc, :category, :weight, :permission, :topic1_id, :topic2_id]
%i[desc category weight permission topic1_id topic2_id]
end
def topic_attributes
[:name, :desc, :link, :permission, :metacode_id]
%i[name desc link permission metacode_id]
end
def mapping_attributes
[:xloc, :yloc, :map_id, :mappable_type, :mappable_id]
%i[xloc yloc map_id mappable_type mappable_id]
end
end

View file

@ -1,20 +1,21 @@
# frozen_string_literal: true
class Star < ActiveRecord::Base
class Star < ApplicationRecord
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

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