Compare commits
481 commits
feature/up
...
develop
Author | SHA1 | Date | |
---|---|---|---|
|
98081097b4 | ||
|
f753392d49 | ||
|
38a209a970 | ||
|
bd7bf20810 | ||
|
955ebdd747 | ||
|
fdcd8a93f1 | ||
|
b5c52adf5e | ||
|
b7761a3627 | ||
|
e0d72fce14 | ||
|
139fdf8e2b | ||
|
4313f6eff8 | ||
|
91c004ebfd | ||
|
96056f43ef | ||
|
32e58fa8af | ||
|
5ebbd87afc | ||
|
006920b686 | ||
|
97448b389f | ||
|
f1ecc9eb0b | ||
|
ca2684fcf3 | ||
|
d9c53514fe | ||
|
e195b89bbd | ||
|
e66498a861 | ||
|
901eb4a513 | ||
|
cbf44e3dfe | ||
|
8b492d6dc8 | ||
|
b83f366284 | ||
|
1ac06d973c | ||
|
9af3754bc8 | ||
|
8169f24072 | ||
|
b9fb4a2829 | ||
|
9b52d0e081 | ||
|
14dc3687cd | ||
|
0a6e7918ef | ||
|
4a7595e76d | ||
|
e899179314 | ||
|
44fec58985 | ||
|
29a25c28a8 | ||
|
76c727cd61 | ||
|
693e6f5e10 | ||
|
a1d4c99ff6 | ||
|
55f2425501 | ||
|
f9c139c19e | ||
|
d51a22c5a9 | ||
|
567bc9d69d | ||
|
15f512efef | ||
|
5e6fb6290c | ||
|
8695297a0f | ||
|
216a19476b | ||
|
a0c9530c91 | ||
|
277644f59d | ||
|
0ffc01b3fb | ||
|
9471efb6bd | ||
|
fc8ac6eef1 | ||
|
9cc700c64d | ||
|
64ffc78f45 | ||
|
322da431eb | ||
|
3c7c8812a4 | ||
|
0d6963ebb0 | ||
|
c4d0bf8ce4 | ||
|
3406f2e04d | ||
|
a4c905df4e | ||
|
5f1fe4dc3f | ||
|
2515073393 | ||
|
a04cd0d395 | ||
|
da9e44afa0 | ||
|
e290244404 | ||
|
6e1878413f | ||
|
77846cfcb7 | ||
|
1ffc513617 | ||
|
3886e62a7b | ||
|
ad2ba33db6 | ||
|
cf9f54c738 | ||
|
f323796030 | ||
|
a080b82e7f | ||
|
1174123b60 | ||
|
35f77129ad | ||
|
a56991aede | ||
|
672b456193 | ||
|
21518c8696 | ||
|
29bf2a23e8 | ||
|
61eac509de | ||
|
4cc420eb63 | ||
|
ec3e09c578 | ||
|
3e03e0ebbf | ||
|
9ab7e7e170 | ||
|
5af2b8f216 | ||
|
8af66b1b2c | ||
|
9b2193ad8c | ||
|
1a8c7810be | ||
|
d87bb7c75c | ||
|
aceb3ff31e | ||
|
f26c6cf0b7 | ||
|
42f4ecb37b | ||
|
64f4249f44 | ||
|
958bd8c70c | ||
|
3830946723 | ||
|
3482e799fd | ||
|
e016b923a4 | ||
|
bb546779cd | ||
|
3829d32390 | ||
|
9783a5ee1e | ||
|
12fc0c71f6 | ||
|
c2cb8949eb | ||
|
4e7bf02749 | ||
|
3203c2b4d0 | ||
|
1ec9dc20e4 | ||
|
1af4728073 | ||
|
785e16eeae | ||
|
d08cb3f95e | ||
|
271fc7ebd0 | ||
|
9d590295cb | ||
|
dc4d44951e | ||
|
767414ad9f | ||
|
1ec897b8c8 | ||
|
00e2aefb4e | ||
|
aec0f104b8 | ||
|
db6d2e77da | ||
|
9585dce511 | ||
|
78acd7e0b0 | ||
|
328c1a14f3 | ||
|
10ac64c574 | ||
|
edce66c44d | ||
|
74df2559a4 | ||
|
a6694a3f72 | ||
|
8c7a657499 | ||
|
90f77cd4f7 | ||
|
af4dc869c0 | ||
|
2cae12e1ab | ||
|
49102ea474 | ||
|
f2a7cc1f19 | ||
|
a5d5cd6000 | ||
|
391a1d8b24 | ||
|
cc17c1ed38 | ||
|
eee1febbf9 | ||
|
c8f6374ac8 | ||
|
ed76162b63 | ||
|
1eb4187691 | ||
|
4a7dd54aca | ||
|
efd6258c7e | ||
|
f4d1b8ba35 | ||
|
47a74dd77b | ||
|
33276444c7 | ||
|
1124d76475 | ||
|
4ffa9460f5 | ||
|
44753dbfe1 | ||
|
77f76b1b5a | ||
|
e544d6a6db | ||
|
780e66632b | ||
|
de4f51bb5c | ||
|
5d0da4c5f1 | ||
|
9079d1bffc | ||
|
962881a35d | ||
|
8483b62603 | ||
|
e3b4dac1e1 | ||
|
8998e3858c | ||
|
ce51eeca8c | ||
|
3178f6e650 | ||
|
7ee96bf6c6 | ||
|
b740fef8fe | ||
|
55b031ccb7 | ||
|
9df389060e | ||
|
153cc38d1a | ||
|
4ff9619837 | ||
|
a6c1c0c730 | ||
|
529dec09a3 | ||
|
ddbaac513f | ||
|
ba943b20f1 | ||
|
4deb3f5ab9 | ||
|
47d0faadf2 | ||
|
9800cc27c6 | ||
|
7840e09e5f | ||
|
687b957737 | ||
|
9ce989eba5 | ||
|
2c85590d65 | ||
|
2b34d84715 | ||
|
013e3c7f21 | ||
|
8d771543d8 | ||
|
50639e8a0a | ||
|
9d52aa9c74 | ||
|
545706e17a | ||
|
95901e17e8 | ||
|
9dbbdf1150 | ||
|
4ee4aeaad2 | ||
|
bfdce21a66 | ||
|
53d4beddec | ||
|
d455ced683 | ||
|
d8698ef6f2 | ||
|
1374da35da | ||
|
2d0d0403b1 | ||
|
2d50f24be6 | ||
|
876c61a18e | ||
|
b0deafc53e | ||
|
a647d80efa | ||
|
559ad230ce | ||
|
26dfcbf823 | ||
|
915defcd1b | ||
|
dde097ea75 | ||
|
3706cd83e7 | ||
|
575a3ec8bf | ||
|
b2bf9978aa | ||
|
0441850504 | ||
|
3ae4072b5d | ||
|
00ecb0f6bb | ||
|
45a15da896 | ||
|
a96c8ae75c | ||
|
a137c21d2d | ||
|
952cf4e79f | ||
|
53bc4ee1c8 | ||
|
c60f7f4525 | ||
|
8df2cd8732 | ||
|
2c6da79df3 | ||
|
6e913efbae | ||
|
db81962c91 | ||
|
8330ef9679 | ||
|
696ff396b0 | ||
|
b16617286f | ||
|
fee011bba6 | ||
|
d16709e8e7 | ||
|
0ad10c0f5a | ||
|
d11278b63b | ||
|
2652d53e9b | ||
|
dc8d274487 | ||
|
2fd972ddce | ||
|
bba8231e8c | ||
|
1229e92feb | ||
|
ba3d5f07dd | ||
|
d47d7e50e7 | ||
|
af2c6ebef1 | ||
|
a9f19815e4 | ||
|
460de840b6 | ||
|
36ed85312e | ||
|
991c4cabdb | ||
|
38004c1f1f | ||
|
cd796f3ade | ||
|
c57015cb15 | ||
|
9223295320 | ||
|
b4bffbe427 | ||
|
6296df1102 | ||
|
2e0acfc170 | ||
|
99b21be27b | ||
|
2c60d7335c | ||
|
6f6e5bea06 | ||
|
6f0d391aaa | ||
|
b1a64c6e7a | ||
|
59b3d254dd | ||
|
f3539f54bf | ||
|
75ccfb0ab3 | ||
|
7b5bd53c28 | ||
|
5302f03196 | ||
|
536c458981 | ||
|
f64612f99b | ||
|
cbc38e0c93 | ||
|
42d671c05b | ||
|
08109ee5de | ||
|
0952c0f3c9 | ||
|
25b4d388de | ||
|
8b738f3d28 | ||
|
da94cd0c8b | ||
|
e9e6b1dc09 | ||
|
e84dfbaa33 | ||
|
cb95e027c4 | ||
|
8e50efb3c1 | ||
|
5ab5f6fec2 | ||
|
cbf1ec3afb | ||
|
d3315d962d | ||
|
ae05fb35d3 | ||
|
9e6ce90950 | ||
|
3868910dde | ||
|
5c1261892f | ||
|
9ada1ca935 | ||
|
df5cc4e1a8 | ||
|
ce073028c8 | ||
|
7d869d7b63 | ||
|
73e8f2d4c8 | ||
|
68f0e91259 | ||
|
b07941834c | ||
|
b914065bb3 | ||
|
33fc27ffd1 | ||
|
7ca7f0862f | ||
|
c604e69d77 | ||
|
fb12c7e202 | ||
|
9ab1c9c647 | ||
|
28d960459e | ||
|
ef84209de1 | ||
|
2d920cf66a | ||
|
40a97a5ae9 | ||
|
186129807e | ||
|
87228c27c1 | ||
|
6d8392d2e7 | ||
|
0960159265 | ||
|
88e98c7342 | ||
|
3f6f020ce1 | ||
|
8e958ec9a8 | ||
|
9debcdde39 | ||
|
b4ad51e69d | ||
|
9b95e91f1a | ||
|
c46e85529e | ||
|
85408a14d3 | ||
|
3b8a5d0c2e | ||
|
6f88c2a7eb | ||
|
f1e62fb6c1 | ||
|
0c52188014 | ||
|
7c0e0f731f | ||
|
1ba339b3be | ||
|
6129a27ecf | ||
|
d51e3f3b52 | ||
|
1317186f63 | ||
|
d6527ea80e | ||
|
a133702be2 | ||
|
d2074ada79 | ||
|
00286fcc29 | ||
|
01cd624bfa | ||
|
a5f793fe54 | ||
|
d1aa62d382 | ||
|
3f161c1076 | ||
|
4da3a9d55f | ||
|
90c5bc26fc | ||
|
5d8ff3efce | ||
|
95b8b52224 | ||
|
55853c60f4 | ||
|
5b90c38b22 | ||
|
c03d6dd5f6 | ||
|
51d5d77629 | ||
|
ce2d462578 | ||
|
4533a0f2fe | ||
|
5851d57eef | ||
|
e1441acde0 | ||
|
d1f75c8c24 | ||
|
83b58d43d5 | ||
|
3759851621 | ||
|
a176cdf231 | ||
|
9df974a037 | ||
|
bd4072f81c | ||
|
6a2646c9cd | ||
|
2f4fe525ce | ||
|
518782e1c7 | ||
|
7c9b6a2205 | ||
|
8026969799 | ||
|
4b500a4428 | ||
|
0778179ba7 | ||
|
bfd23c6d32 | ||
|
9cb3074245 | ||
|
e4d193572f | ||
|
0f85abfda2 | ||
|
887c3f7570 | ||
|
667f5653a7 | ||
|
48b93b2269 | ||
|
9ad4684825 | ||
|
f516e1e73d | ||
|
2588636837 | ||
|
644df6fcdc | ||
|
c10a4f4837 | ||
|
304722b528 | ||
|
a9c67e70d4 | ||
|
ed3e4780d2 | ||
|
b013499c76 | ||
|
5270c5a611 | ||
|
5cfa8ffdc7 | ||
|
814c1acc0f | ||
|
62e2acdd52 | ||
|
151e96f803 | ||
|
bc1f212c93 | ||
|
b9190233b1 | ||
|
5e0e44b436 | ||
|
1fbfd56d57 | ||
|
a32f98bde2 | ||
|
6cc827d11c | ||
|
de16420796 | ||
|
e49e5c258a | ||
|
4dc32d7d2e | ||
|
9d821c920b | ||
|
6b1220b533 | ||
|
4f3d12d7a5 | ||
|
7b4a072fd8 | ||
|
175a3ee73e | ||
|
b13587456d | ||
|
f023a18069 | ||
|
e640048386 | ||
|
98725b3ee4 | ||
|
8a95262f2c | ||
|
ed89f80f49 | ||
|
47bca5907e | ||
|
5163794698 | ||
|
0b6348e13f | ||
|
ce1205f6d7 | ||
|
96d25cc91d | ||
|
a9ef6feebd | ||
|
98e2de68da | ||
|
4c68fd90ca | ||
|
cda0c21a0b | ||
|
a44edbb17e | ||
|
aa96d074af | ||
|
4f9b9460ad | ||
|
a63cd02bc6 | ||
|
fb6c8a74a7 | ||
|
5db8e27496 | ||
|
87dc20fa50 | ||
|
154257d062 | ||
|
497c6ae017 | ||
|
9600983311 | ||
|
cbcdd912c9 | ||
|
1d13da4ab5 | ||
|
d359eb063a | ||
|
4187dbd803 | ||
|
d549083cce | ||
|
bc8660c83e | ||
|
c0b35280f6 | ||
|
31078c554e | ||
|
ea20ba45b3 | ||
|
37b989c38e | ||
|
759ec7845b | ||
|
cfb8f51214 | ||
|
1cd7e22c40 | ||
|
ad1889dfc5 | ||
|
cbc8e6cdd4 | ||
|
f8556c30a5 | ||
|
8af1e69460 | ||
|
d1e8ecbf3b | ||
|
8e38469b1f | ||
|
abb997c75c | ||
|
be8efa6025 | ||
|
439527c464 | ||
|
f68deea202 | ||
|
b61cdb04fc | ||
|
5c67fcbff7 | ||
|
2eeb0a671f | ||
|
fb427a11f0 | ||
|
7a09a1c620 | ||
|
103ed5cbd7 | ||
|
b1a7e548a2 | ||
|
52c340b8f5 | ||
|
9299ca5f2c | ||
|
261ed49977 | ||
|
e2d9b6aef2 | ||
|
1042fb020d | ||
|
7f1c04015e | ||
|
f75d5253b3 | ||
|
bb6566a45e | ||
|
2529e0d44f | ||
|
139837e997 | ||
|
d8cd536a95 | ||
|
29913cd10b | ||
|
d004e98ada | ||
|
d2e097fd05 | ||
|
fe0da255dd | ||
|
6e75274737 | ||
|
6c9d464a9f | ||
|
517cfcb913 | ||
|
0ee1b3284a | ||
|
b976c13db2 | ||
|
c0955d7c5e | ||
|
332bb2ec08 | ||
|
179849b639 | ||
|
4f6dae304c | ||
|
3479fb7ff7 | ||
|
c113253fc5 | ||
|
e46aa54ba3 | ||
|
4602ded8a4 | ||
|
14ea18a967 | ||
|
8180a8cc71 | ||
|
da5191171a | ||
|
26a8cddd14 | ||
|
407ac1f29c | ||
|
fc2849824f | ||
|
6f3c74b7f1 | ||
|
c3dbd59280 | ||
|
0e7e649f56 | ||
|
6e03132f1b | ||
|
b2a4acc99d | ||
|
7eae8deacb | ||
|
62c489cba7 | ||
|
3051723bcf | ||
|
858ca66d69 | ||
|
a0c0dcbc79 | ||
|
6e6d33abbe | ||
|
b6da38e29e | ||
|
3e4ff59a82 | ||
|
08f89ee630 | ||
|
b978247785 | ||
|
0aeb6caadb | ||
|
eaffc346fd |
558 changed files with 22269 additions and 24900 deletions
.agignore.codeclimate.yml.eslintrc.js.example-env.gitignore.rubocop.yml.simplecov.travis.ymlGemfileGemfile.lockProcfileREADME.mdRakefileVagrantfile
app
assets
config
images
.DS_Storearrowperms_sprite.pngimport.pngjunto.gifmetadata.pngmetamaps-intro-poster.webptopright_sprite.pnguser_sprite.pngview-only.png
javascripts
Metamaps.ServerData.js.erbapplication-secret.jsapplication.jscloudcarousel-secret.jshomepageVimeoFallback.js.erb
lib
WebSocketMain.swfWebSocketMainInsecure.swfajaxq.jsattachMediaStream.jscanvas-to-blob.min.jscloudcarousel.jshowler.jssimplewebrtc.bundle.jssocket.io.jssocketIoConnection.jsuservoice.js
metamaps.secret.bundle.jssrc
secret_stylesheets
stylesheets
channels
controllers
access_controller.rbapplication_controller.rbexplore_controller.rbhacks_controller.rbmain_controller.rbmappings_controller.rbmaps_controller.rbmessages_controller.rbmetacode_sets_controller.rbmetacodes_controller.rbnotifications_controller.rbsearch_controller.rbstars_controller.rbsynapses_controller.rbtokens_controller.rbtopics_controller.rb
api
v1
v2
users
users_controller.rbdecorators
helpers
1
.agignore
Normal file
1
.agignore
Normal file
|
@ -0,0 +1 @@
|
||||||
|
app/assets/javascripts/metamaps.secret.bundle.js
|
|
@ -8,6 +8,7 @@ engines:
|
||||||
enabled: true
|
enabled: true
|
||||||
config:
|
config:
|
||||||
languages:
|
languages:
|
||||||
|
count_threshold: 3 # rule of three
|
||||||
ruby:
|
ruby:
|
||||||
mass_threshold: 36 # default: 18
|
mass_threshold: 36 # default: 18
|
||||||
javascript:
|
javascript:
|
||||||
|
@ -19,6 +20,8 @@ engines:
|
||||||
enabled: true
|
enabled: true
|
||||||
rubocop:
|
rubocop:
|
||||||
enabled: true
|
enabled: true
|
||||||
|
exclude_fingerprints:
|
||||||
|
- 74f18007b920e8d81148d2f6a2756534
|
||||||
ratings:
|
ratings:
|
||||||
paths:
|
paths:
|
||||||
- 'Gemfile.lock'
|
- 'Gemfile.lock'
|
||||||
|
|
|
@ -20,6 +20,7 @@ module.exports = {
|
||||||
"rules": {
|
"rules": {
|
||||||
"react/jsx-uses-react": [2],
|
"react/jsx-uses-react": [2],
|
||||||
"react/jsx-uses-vars": [2],
|
"react/jsx-uses-vars": [2],
|
||||||
|
"space-before-function-paren": [2, "never"],
|
||||||
"yoda": [2, "never", { "exceptRange": true }]
|
"yoda": [2, "never", { "exceptRange": true }]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,10 +1,14 @@
|
||||||
|
# Node JS env
|
||||||
|
export NODE_REALTIME_PORT='5000' # should match REALTIME_SERVER, below
|
||||||
|
|
||||||
|
# Rails env
|
||||||
export DB_USERNAME='postgres'
|
export DB_USERNAME='postgres'
|
||||||
export DB_PASSWORD='3112'
|
export DB_PASSWORD='3112'
|
||||||
export DB_HOST='localhost'
|
export DB_HOST='localhost'
|
||||||
export DB_PORT='5432'
|
export DB_PORT='5432'
|
||||||
export DB_NAME='metamap002'
|
export DB_NAME='metamaps'
|
||||||
|
|
||||||
export REALTIME_SERVER='http://localhost:5001'
|
export REALTIME_SERVER='http://localhost:5000'
|
||||||
export MAILER_DEFAULT_URL='localhost:3000'
|
export MAILER_DEFAULT_URL='localhost:3000'
|
||||||
export DEVISE_MAILER_SENDER='team@metamaps.cc'
|
export DEVISE_MAILER_SENDER='team@metamaps.cc'
|
||||||
|
|
||||||
|
@ -18,7 +22,6 @@ export SECRET_KEY_BASE='267c8a84f63963282f45bc3010eaddf027abfab58fc759d6e239c800
|
||||||
# export S3_BUCKET_NAME
|
# export S3_BUCKET_NAME
|
||||||
# export AWS_ACCESS_KEY_ID
|
# export AWS_ACCESS_KEY_ID
|
||||||
# export AWS_SECRET_ACCESS_KEY
|
# export AWS_SECRET_ACCESS_KEY
|
||||||
# export SSO_KEY
|
|
||||||
#
|
#
|
||||||
# export SMTP_DOMAIN
|
# export SMTP_DOMAIN
|
||||||
# export SMTP_PASSWORD
|
# export SMTP_PASSWORD
|
||||||
|
|
4
.gitignore
vendored
4
.gitignore
vendored
|
@ -15,6 +15,7 @@ app/assets/javascripts/webpacked
|
||||||
|
|
||||||
#secrets and config
|
#secrets and config
|
||||||
.env
|
.env
|
||||||
|
*.swp
|
||||||
|
|
||||||
# Ignore bundler config
|
# Ignore bundler config
|
||||||
.bundle
|
.bundle
|
||||||
|
@ -22,6 +23,7 @@ app/assets/javascripts/webpacked
|
||||||
# Ignore all logfiles and tempfiles.
|
# Ignore all logfiles and tempfiles.
|
||||||
log/*.log
|
log/*.log
|
||||||
tmp
|
tmp
|
||||||
|
.tmp
|
||||||
|
|
||||||
coverage
|
coverage
|
||||||
|
|
||||||
|
@ -29,3 +31,5 @@ coverage
|
||||||
*/.DS_Store
|
*/.DS_Store
|
||||||
.DS_Store?
|
.DS_Store?
|
||||||
.vagrant
|
.vagrant
|
||||||
|
gentle/
|
||||||
|
startserver.sh
|
||||||
|
|
10
.rubocop.yml
10
.rubocop.yml
|
@ -12,10 +12,18 @@ Rails:
|
||||||
Enabled: true
|
Enabled: true
|
||||||
|
|
||||||
Metrics/LineLength:
|
Metrics/LineLength:
|
||||||
Max: 100
|
Max: 120
|
||||||
|
|
||||||
Metrics/AbcSize:
|
Metrics/AbcSize:
|
||||||
Max: 16
|
Max: 16
|
||||||
|
|
||||||
Style/Documentation:
|
Style/Documentation:
|
||||||
Enabled: false
|
Enabled: false
|
||||||
|
|
||||||
|
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
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
if ENV['COVERAGE'] == 'on'
|
if ENV['COVERAGE'] == 'on'
|
||||||
SimpleCov.start 'rails'
|
SimpleCov.start 'rails' do
|
||||||
|
add_group 'Policies', 'app/policies'
|
||||||
|
add_group 'Services', 'app/services'
|
||||||
|
add_group 'Serializers', 'app/serializers'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -22,3 +22,4 @@ script:
|
||||||
addons:
|
addons:
|
||||||
code_climate:
|
code_climate:
|
||||||
repo_token: 479d3bf56798fbc7fff3fc8151a5ed09e8ac368fd5af332c437b9e07dbebb44e
|
repo_token: 479d3bf56798fbc7fff3fc8151a5ed09e8ac368fd5af332c437b9e07dbebb44e
|
||||||
|
postgresql: "9.4"
|
||||||
|
|
18
Gemfile
18
Gemfile
|
@ -1,11 +1,12 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
ruby '2.3.0'
|
ruby '2.3.0'
|
||||||
|
|
||||||
gem 'rails', '~> 5.0.0'
|
gem 'rails', '~> 5.0.0'
|
||||||
|
|
||||||
gem 'active_model_serializers'
|
gem 'active_model_serializers'
|
||||||
gem 'aws-sdk'
|
gem 'aws-sdk', '~> 2.7.0'
|
||||||
gem 'best_in_place'
|
gem 'best_in_place'
|
||||||
gem 'delayed_job'
|
gem 'delayed_job'
|
||||||
gem 'delayed_job_active_record'
|
gem 'delayed_job_active_record'
|
||||||
|
@ -16,38 +17,41 @@ gem 'exception_notification'
|
||||||
gem 'httparty'
|
gem 'httparty'
|
||||||
gem 'json'
|
gem 'json'
|
||||||
gem 'kaminari'
|
gem 'kaminari'
|
||||||
|
gem 'mailboxer'
|
||||||
gem 'paperclip'
|
gem 'paperclip'
|
||||||
gem 'pg'
|
gem 'pg'
|
||||||
|
gem 'puma'
|
||||||
gem 'pundit'
|
gem 'pundit'
|
||||||
gem 'pundit_extra'
|
gem 'pundit_extra'
|
||||||
gem 'rack-attack'
|
gem 'rack-attack'
|
||||||
gem 'rack-cors'
|
gem 'rack-cors'
|
||||||
gem 'redis'
|
gem 'redis', '~> 3.3.3'
|
||||||
gem 'slack-notifier'
|
gem 'slack-notifier'
|
||||||
gem 'snorlax'
|
gem 'snorlax'
|
||||||
gem 'uservoice-ruby'
|
gem 'sucker_punch'
|
||||||
|
|
||||||
# asset stuff
|
# asset stuff
|
||||||
gem 'coffee-rails'
|
|
||||||
gem 'jquery-rails'
|
gem 'jquery-rails'
|
||||||
gem 'jquery-ui-rails'
|
gem 'jquery-ui-rails'
|
||||||
gem 'sass-rails'
|
gem 'sass-rails'
|
||||||
gem 'uglifier'
|
gem 'uglifier'
|
||||||
|
|
||||||
group :test do
|
group :test do
|
||||||
gem 'factory_girl_rails'
|
gem 'brakeman', require: false
|
||||||
|
gem 'factory_bot_rails'
|
||||||
gem 'json-schema'
|
gem 'json-schema'
|
||||||
gem 'rspec-rails'
|
gem 'rspec-rails'
|
||||||
gem 'shoulda-matchers'
|
gem 'shoulda-matchers'
|
||||||
gem 'simplecov', require: false
|
gem 'simplecov', require: false
|
||||||
gem 'brakeman', require: false
|
|
||||||
end
|
end
|
||||||
|
|
||||||
group :development, :test do
|
group :development, :test do
|
||||||
gem 'better_errors'
|
gem 'better_errors'
|
||||||
gem 'binding_of_caller'
|
gem 'binding_of_caller'
|
||||||
|
gem 'faker'
|
||||||
gem 'pry-byebug'
|
gem 'pry-byebug'
|
||||||
gem 'pry-rails'
|
gem 'pry-rails'
|
||||||
|
gem 'rubocop', '~> 0.48.1' # match code climate https://github.com/tootsuite/mastodon/issues/1758
|
||||||
|
gem 'timecop'
|
||||||
gem 'tunemygc'
|
gem 'tunemygc'
|
||||||
gem 'rubocop'
|
|
||||||
end
|
end
|
||||||
|
|
354
Gemfile.lock
354
Gemfile.lock
|
@ -1,274 +1,297 @@
|
||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
actioncable (5.0.0.1)
|
actioncable (5.0.5)
|
||||||
actionpack (= 5.0.0.1)
|
actionpack (= 5.0.5)
|
||||||
nio4r (~> 1.2)
|
nio4r (>= 1.2, < 3.0)
|
||||||
websocket-driver (~> 0.6.1)
|
websocket-driver (~> 0.6.1)
|
||||||
actionmailer (5.0.0.1)
|
actionmailer (5.0.5)
|
||||||
actionpack (= 5.0.0.1)
|
actionpack (= 5.0.5)
|
||||||
actionview (= 5.0.0.1)
|
actionview (= 5.0.5)
|
||||||
activejob (= 5.0.0.1)
|
activejob (= 5.0.5)
|
||||||
mail (~> 2.5, >= 2.5.4)
|
mail (~> 2.5, >= 2.5.4)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
actionpack (5.0.0.1)
|
actionpack (5.0.5)
|
||||||
actionview (= 5.0.0.1)
|
actionview (= 5.0.5)
|
||||||
activesupport (= 5.0.0.1)
|
activesupport (= 5.0.5)
|
||||||
rack (~> 2.0)
|
rack (~> 2.0)
|
||||||
rack-test (~> 0.6.3)
|
rack-test (~> 0.6.3)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||||
actionview (5.0.0.1)
|
actionview (5.0.5)
|
||||||
activesupport (= 5.0.0.1)
|
activesupport (= 5.0.5)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
erubis (~> 2.7.0)
|
erubis (~> 2.7.0)
|
||||||
rails-dom-testing (~> 2.0)
|
rails-dom-testing (~> 2.0)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
rails-html-sanitizer (~> 1.0, >= 1.0.3)
|
||||||
active_model_serializers (0.10.2)
|
active_model_serializers (0.10.6)
|
||||||
actionpack (>= 4.1, < 6)
|
actionpack (>= 4.1, < 6)
|
||||||
activemodel (>= 4.1, < 6)
|
activemodel (>= 4.1, < 6)
|
||||||
jsonapi (~> 0.1.1.beta2)
|
case_transform (>= 0.2)
|
||||||
railties (>= 4.1, < 6)
|
jsonapi-renderer (>= 0.1.1.beta1, < 0.2)
|
||||||
activejob (5.0.0.1)
|
activejob (5.0.5)
|
||||||
activesupport (= 5.0.0.1)
|
activesupport (= 5.0.5)
|
||||||
globalid (>= 0.3.6)
|
globalid (>= 0.3.6)
|
||||||
activemodel (5.0.0.1)
|
activemodel (5.0.5)
|
||||||
activesupport (= 5.0.0.1)
|
activesupport (= 5.0.5)
|
||||||
activerecord (5.0.0.1)
|
activerecord (5.0.5)
|
||||||
activemodel (= 5.0.0.1)
|
activemodel (= 5.0.5)
|
||||||
activesupport (= 5.0.0.1)
|
activesupport (= 5.0.5)
|
||||||
arel (~> 7.0)
|
arel (~> 7.0)
|
||||||
activesupport (5.0.0.1)
|
activesupport (5.0.5)
|
||||||
concurrent-ruby (~> 1.0, >= 1.0.2)
|
concurrent-ruby (~> 1.0, >= 1.0.2)
|
||||||
i18n (~> 0.7)
|
i18n (~> 0.7)
|
||||||
minitest (~> 5.1)
|
minitest (~> 5.1)
|
||||||
tzinfo (~> 1.1)
|
tzinfo (~> 1.1)
|
||||||
addressable (2.3.8)
|
addressable (2.5.2)
|
||||||
arel (7.1.2)
|
public_suffix (>= 2.0.2, < 4.0)
|
||||||
|
arel (7.1.4)
|
||||||
ast (2.3.0)
|
ast (2.3.0)
|
||||||
aws-sdk (2.6.3)
|
aws-sdk (2.7.0)
|
||||||
aws-sdk-resources (= 2.6.3)
|
aws-sdk-resources (= 2.7.0)
|
||||||
aws-sdk-core (2.6.3)
|
aws-sdk-core (2.7.0)
|
||||||
|
aws-sigv4 (~> 1.0)
|
||||||
jmespath (~> 1.0)
|
jmespath (~> 1.0)
|
||||||
aws-sdk-resources (2.6.3)
|
aws-sdk-resources (2.7.0)
|
||||||
aws-sdk-core (= 2.6.3)
|
aws-sdk-core (= 2.7.0)
|
||||||
|
aws-sigv4 (1.0.2)
|
||||||
bcrypt (3.1.11)
|
bcrypt (3.1.11)
|
||||||
best_in_place (3.1.0)
|
best_in_place (3.1.1)
|
||||||
actionpack (>= 3.2)
|
actionpack (>= 3.2)
|
||||||
railties (>= 3.2)
|
railties (>= 3.2)
|
||||||
better_errors (2.1.1)
|
better_errors (2.3.0)
|
||||||
coderay (>= 1.0.0)
|
coderay (>= 1.0.0)
|
||||||
erubis (>= 2.6.6)
|
erubi (>= 1.0.0)
|
||||||
rack (>= 0.9.0)
|
rack (>= 0.9.0)
|
||||||
binding_of_caller (0.7.2)
|
binding_of_caller (0.7.2)
|
||||||
debug_inspector (>= 0.0.1)
|
debug_inspector (>= 0.0.1)
|
||||||
brakeman (3.4.0)
|
brakeman (3.7.2)
|
||||||
builder (3.2.2)
|
builder (3.2.3)
|
||||||
byebug (9.0.5)
|
byebug (9.1.0)
|
||||||
climate_control (0.0.3)
|
carrierwave (1.1.0)
|
||||||
activesupport (>= 3.0)
|
activemodel (>= 4.0.0)
|
||||||
|
activesupport (>= 4.0.0)
|
||||||
|
mime-types (>= 1.16)
|
||||||
|
case_transform (0.2)
|
||||||
|
activesupport
|
||||||
|
climate_control (0.2.0)
|
||||||
cocaine (0.5.8)
|
cocaine (0.5.8)
|
||||||
climate_control (>= 0.0.3, < 1.0)
|
climate_control (>= 0.0.3, < 1.0)
|
||||||
coderay (1.1.1)
|
coderay (1.1.2)
|
||||||
coffee-rails (4.2.1)
|
concurrent-ruby (1.0.5)
|
||||||
coffee-script (>= 2.2.0)
|
debug_inspector (0.0.3)
|
||||||
railties (>= 4.0.0, < 5.2.x)
|
delayed_job (4.1.3)
|
||||||
coffee-script (2.4.1)
|
activesupport (>= 3.0, < 5.2)
|
||||||
coffee-script-source
|
delayed_job_active_record (4.1.2)
|
||||||
execjs
|
activerecord (>= 3.0, < 5.2)
|
||||||
coffee-script-source (1.10.0)
|
|
||||||
concurrent-ruby (1.0.2)
|
|
||||||
debug_inspector (0.0.2)
|
|
||||||
delayed_job (4.1.2)
|
|
||||||
activesupport (>= 3.0, < 5.1)
|
|
||||||
delayed_job_active_record (4.1.1)
|
|
||||||
activerecord (>= 3.0, < 5.1)
|
|
||||||
delayed_job (>= 3.0, < 5)
|
delayed_job (>= 3.0, < 5)
|
||||||
devise (4.2.0)
|
devise (4.3.0)
|
||||||
bcrypt (~> 3.0)
|
bcrypt (~> 3.0)
|
||||||
orm_adapter (~> 0.1)
|
orm_adapter (~> 0.1)
|
||||||
railties (>= 4.1.0, < 5.1)
|
railties (>= 4.1.0, < 5.2)
|
||||||
responders
|
responders
|
||||||
warden (~> 1.2.3)
|
warden (~> 1.2.3)
|
||||||
diff-lcs (1.2.5)
|
diff-lcs (1.3)
|
||||||
docile (1.1.5)
|
docile (1.1.5)
|
||||||
doorkeeper (4.2.0)
|
doorkeeper (4.2.6)
|
||||||
railties (>= 4.2)
|
railties (>= 4.2)
|
||||||
dotenv (2.1.1)
|
dotenv (2.2.1)
|
||||||
dotenv-rails (2.1.1)
|
dotenv-rails (2.2.1)
|
||||||
dotenv (= 2.1.1)
|
dotenv (= 2.2.1)
|
||||||
railties (>= 4.0, < 5.1)
|
railties (>= 3.2, < 5.2)
|
||||||
|
erubi (1.6.1)
|
||||||
erubis (2.7.0)
|
erubis (2.7.0)
|
||||||
exception_notification (4.2.1)
|
exception_notification (4.2.2)
|
||||||
actionmailer (>= 4.0, < 6)
|
actionmailer (>= 4.0, < 6)
|
||||||
activesupport (>= 4.0, < 6)
|
activesupport (>= 4.0, < 6)
|
||||||
execjs (2.7.0)
|
execjs (2.7.0)
|
||||||
ezcrypto (0.7.2)
|
factory_bot (4.8.2)
|
||||||
factory_girl (4.7.0)
|
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
factory_girl_rails (4.7.0)
|
factory_bot_rails (4.8.2)
|
||||||
factory_girl (~> 4.7.0)
|
factory_bot (~> 4.8.2)
|
||||||
railties (>= 3.0.0)
|
railties (>= 3.0.0)
|
||||||
globalid (0.3.7)
|
faker (1.8.4)
|
||||||
activesupport (>= 4.1.0)
|
i18n (~> 0.5)
|
||||||
httparty (0.14.0)
|
ffi (1.9.18)
|
||||||
|
globalid (0.4.0)
|
||||||
|
activesupport (>= 4.2.0)
|
||||||
|
httparty (0.15.6)
|
||||||
multi_xml (>= 0.5.2)
|
multi_xml (>= 0.5.2)
|
||||||
i18n (0.7.0)
|
i18n (0.9.3)
|
||||||
|
concurrent-ruby (~> 1.0)
|
||||||
jmespath (1.3.1)
|
jmespath (1.3.1)
|
||||||
jquery-rails (4.2.1)
|
jquery-rails (4.3.1)
|
||||||
rails-dom-testing (>= 1, < 3)
|
rails-dom-testing (>= 1, < 3)
|
||||||
railties (>= 4.2.0)
|
railties (>= 4.2.0)
|
||||||
thor (>= 0.14, < 2.0)
|
thor (>= 0.14, < 2.0)
|
||||||
jquery-ui-rails (5.0.5)
|
jquery-ui-rails (6.0.1)
|
||||||
railties (>= 3.2.16)
|
railties (>= 3.2.16)
|
||||||
json (1.8.3)
|
json (2.1.0)
|
||||||
json-schema (2.6.2)
|
json-schema (2.8.0)
|
||||||
addressable (~> 2.3.8)
|
addressable (>= 2.4)
|
||||||
jsonapi (0.1.1.beta2)
|
jsonapi-renderer (0.1.3)
|
||||||
json (~> 1.8)
|
kaminari (1.0.1)
|
||||||
kaminari (0.17.0)
|
activesupport (>= 4.1.0)
|
||||||
actionpack (>= 3.0.0)
|
kaminari-actionview (= 1.0.1)
|
||||||
activesupport (>= 3.0.0)
|
kaminari-activerecord (= 1.0.1)
|
||||||
|
kaminari-core (= 1.0.1)
|
||||||
|
kaminari-actionview (1.0.1)
|
||||||
|
actionview
|
||||||
|
kaminari-core (= 1.0.1)
|
||||||
|
kaminari-activerecord (1.0.1)
|
||||||
|
activerecord
|
||||||
|
kaminari-core (= 1.0.1)
|
||||||
|
kaminari-core (1.0.1)
|
||||||
loofah (2.0.3)
|
loofah (2.0.3)
|
||||||
nokogiri (>= 1.5.9)
|
nokogiri (>= 1.5.9)
|
||||||
mail (2.6.4)
|
mail (2.6.6)
|
||||||
mime-types (>= 1.16, < 4)
|
mime-types (>= 1.16, < 4)
|
||||||
|
mailboxer (0.15.1)
|
||||||
|
carrierwave (>= 0.5.8)
|
||||||
|
rails (>= 5.0.0)
|
||||||
method_source (0.8.2)
|
method_source (0.8.2)
|
||||||
mime-types (3.1)
|
mime-types (3.1)
|
||||||
mime-types-data (~> 3.2015)
|
mime-types-data (~> 3.2015)
|
||||||
mime-types-data (3.2016.0521)
|
mime-types-data (3.2016.0521)
|
||||||
mimemagic (0.3.2)
|
mimemagic (0.3.2)
|
||||||
mini_portile2 (2.1.0)
|
mini_portile2 (2.3.0)
|
||||||
minitest (5.9.1)
|
minitest (5.11.1)
|
||||||
multi_xml (0.5.5)
|
multi_xml (0.6.0)
|
||||||
nio4r (1.2.1)
|
nio4r (2.1.0)
|
||||||
nokogiri (1.6.8)
|
nokogiri (1.8.1)
|
||||||
mini_portile2 (~> 2.1.0)
|
mini_portile2 (~> 2.3.0)
|
||||||
pkg-config (~> 1.1.7)
|
|
||||||
oauth (0.5.1)
|
|
||||||
orm_adapter (0.5.0)
|
orm_adapter (0.5.0)
|
||||||
paperclip (5.1.0)
|
paperclip (5.2.0)
|
||||||
activemodel (>= 4.2.0)
|
activemodel (>= 4.2.0)
|
||||||
activesupport (>= 4.2.0)
|
activesupport (>= 4.2.0)
|
||||||
cocaine (~> 0.5.5)
|
cocaine (~> 0.5.5)
|
||||||
mime-types
|
mime-types
|
||||||
mimemagic (~> 0.3.0)
|
mimemagic (~> 0.3.0)
|
||||||
parser (2.3.1.4)
|
parser (2.4.0.2)
|
||||||
ast (~> 2.2)
|
ast (~> 2.3)
|
||||||
pg (0.19.0)
|
pg (0.21.0)
|
||||||
pkg-config (1.1.7)
|
|
||||||
powerpack (0.1.1)
|
powerpack (0.1.1)
|
||||||
pry (0.10.4)
|
pry (0.10.4)
|
||||||
coderay (~> 1.1.0)
|
coderay (~> 1.1.0)
|
||||||
method_source (~> 0.8.1)
|
method_source (~> 0.8.1)
|
||||||
slop (~> 3.4)
|
slop (~> 3.4)
|
||||||
pry-byebug (3.4.0)
|
pry-byebug (3.5.0)
|
||||||
byebug (~> 9.0)
|
byebug (~> 9.1)
|
||||||
pry (~> 0.10)
|
pry (~> 0.10)
|
||||||
pry-rails (0.3.4)
|
pry-rails (0.3.6)
|
||||||
pry (>= 0.9.10)
|
pry (>= 0.10.4)
|
||||||
|
public_suffix (3.0.0)
|
||||||
|
puma (3.10.0)
|
||||||
pundit (1.1.0)
|
pundit (1.1.0)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
pundit_extra (0.3.0)
|
pundit_extra (0.3.0)
|
||||||
rack (2.0.1)
|
rack (2.0.3)
|
||||||
rack-attack (5.0.1)
|
rack-attack (5.0.1)
|
||||||
rack
|
rack
|
||||||
rack-cors (0.4.0)
|
rack-cors (1.0.1)
|
||||||
rack-test (0.6.3)
|
rack-test (0.6.3)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
rails (5.0.0.1)
|
rails (5.0.5)
|
||||||
actioncable (= 5.0.0.1)
|
actioncable (= 5.0.5)
|
||||||
actionmailer (= 5.0.0.1)
|
actionmailer (= 5.0.5)
|
||||||
actionpack (= 5.0.0.1)
|
actionpack (= 5.0.5)
|
||||||
actionview (= 5.0.0.1)
|
actionview (= 5.0.5)
|
||||||
activejob (= 5.0.0.1)
|
activejob (= 5.0.5)
|
||||||
activemodel (= 5.0.0.1)
|
activemodel (= 5.0.5)
|
||||||
activerecord (= 5.0.0.1)
|
activerecord (= 5.0.5)
|
||||||
activesupport (= 5.0.0.1)
|
activesupport (= 5.0.5)
|
||||||
bundler (>= 1.3.0, < 2.0)
|
bundler (>= 1.3.0)
|
||||||
railties (= 5.0.0.1)
|
railties (= 5.0.5)
|
||||||
sprockets-rails (>= 2.0.0)
|
sprockets-rails (>= 2.0.0)
|
||||||
rails-dom-testing (2.0.1)
|
rails-dom-testing (2.0.3)
|
||||||
activesupport (>= 4.2.0, < 6.0)
|
activesupport (>= 4.2.0)
|
||||||
nokogiri (~> 1.6.0)
|
nokogiri (>= 1.6)
|
||||||
rails-html-sanitizer (1.0.3)
|
rails-html-sanitizer (1.0.3)
|
||||||
loofah (~> 2.0)
|
loofah (~> 2.0)
|
||||||
railties (5.0.0.1)
|
railties (5.0.5)
|
||||||
actionpack (= 5.0.0.1)
|
actionpack (= 5.0.5)
|
||||||
activesupport (= 5.0.0.1)
|
activesupport (= 5.0.5)
|
||||||
method_source
|
method_source
|
||||||
rake (>= 0.8.7)
|
rake (>= 0.8.7)
|
||||||
thor (>= 0.18.1, < 2.0)
|
thor (>= 0.18.1, < 2.0)
|
||||||
rainbow (2.1.0)
|
rainbow (2.2.2)
|
||||||
rake (11.3.0)
|
rake
|
||||||
redis (3.3.1)
|
rake (12.3.0)
|
||||||
responders (2.3.0)
|
rb-fsevent (0.10.2)
|
||||||
railties (>= 4.2.0, < 5.1)
|
rb-inotify (0.9.10)
|
||||||
rspec-core (3.5.3)
|
ffi (>= 0.5.0, < 2)
|
||||||
rspec-support (~> 3.5.0)
|
redis (3.3.3)
|
||||||
rspec-expectations (3.5.0)
|
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)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.5.0)
|
rspec-support (~> 3.6.0)
|
||||||
rspec-mocks (3.5.0)
|
rspec-mocks (3.6.0)
|
||||||
diff-lcs (>= 1.2.0, < 2.0)
|
diff-lcs (>= 1.2.0, < 2.0)
|
||||||
rspec-support (~> 3.5.0)
|
rspec-support (~> 3.6.0)
|
||||||
rspec-rails (3.5.2)
|
rspec-rails (3.6.1)
|
||||||
actionpack (>= 3.0)
|
actionpack (>= 3.0)
|
||||||
activesupport (>= 3.0)
|
activesupport (>= 3.0)
|
||||||
railties (>= 3.0)
|
railties (>= 3.0)
|
||||||
rspec-core (~> 3.5.0)
|
rspec-core (~> 3.6.0)
|
||||||
rspec-expectations (~> 3.5.0)
|
rspec-expectations (~> 3.6.0)
|
||||||
rspec-mocks (~> 3.5.0)
|
rspec-mocks (~> 3.6.0)
|
||||||
rspec-support (~> 3.5.0)
|
rspec-support (~> 3.6.0)
|
||||||
rspec-support (3.5.0)
|
rspec-support (3.6.0)
|
||||||
rubocop (0.43.0)
|
rubocop (0.48.1)
|
||||||
parser (>= 2.3.1.1, < 3.0)
|
parser (>= 2.3.3.1, < 3.0)
|
||||||
powerpack (~> 0.1)
|
powerpack (~> 0.1)
|
||||||
rainbow (>= 1.99.1, < 3.0)
|
rainbow (>= 1.99.1, < 3.0)
|
||||||
ruby-progressbar (~> 1.7)
|
ruby-progressbar (~> 1.7)
|
||||||
unicode-display_width (~> 1.0, >= 1.0.1)
|
unicode-display_width (~> 1.0, >= 1.0.1)
|
||||||
ruby-progressbar (1.8.1)
|
ruby-progressbar (1.9.0)
|
||||||
sass (3.4.22)
|
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)
|
sass-rails (5.0.6)
|
||||||
railties (>= 4.0.0, < 6)
|
railties (>= 4.0.0, < 6)
|
||||||
sass (~> 3.1)
|
sass (~> 3.1)
|
||||||
sprockets (>= 2.8, < 4.0)
|
sprockets (>= 2.8, < 4.0)
|
||||||
sprockets-rails (>= 2.0, < 4.0)
|
sprockets-rails (>= 2.0, < 4.0)
|
||||||
tilt (>= 1.1, < 3)
|
tilt (>= 1.1, < 3)
|
||||||
shoulda-matchers (3.1.1)
|
shoulda-matchers (3.1.2)
|
||||||
activesupport (>= 4.0.0)
|
activesupport (>= 4.0.0)
|
||||||
simplecov (0.12.0)
|
simplecov (0.15.0)
|
||||||
docile (~> 1.1.0)
|
docile (~> 1.1.0)
|
||||||
json (>= 1.8, < 3)
|
json (>= 1.8, < 3)
|
||||||
simplecov-html (~> 0.10.0)
|
simplecov-html (~> 0.10.0)
|
||||||
simplecov-html (0.10.0)
|
simplecov-html (0.10.2)
|
||||||
slack-notifier (1.5.1)
|
slack-notifier (2.3.1)
|
||||||
slop (3.6.0)
|
slop (3.6.0)
|
||||||
snorlax (0.1.6)
|
snorlax (0.1.6)
|
||||||
rails (> 4.1)
|
rails (> 4.1)
|
||||||
sprockets (3.7.0)
|
sprockets (3.7.1)
|
||||||
concurrent-ruby (~> 1.0)
|
concurrent-ruby (~> 1.0)
|
||||||
rack (> 1, < 3)
|
rack (> 1, < 3)
|
||||||
sprockets-rails (3.2.0)
|
sprockets-rails (3.2.1)
|
||||||
actionpack (>= 4.0)
|
actionpack (>= 4.0)
|
||||||
activesupport (>= 4.0)
|
activesupport (>= 4.0)
|
||||||
sprockets (>= 3.0.0)
|
sprockets (>= 3.0.0)
|
||||||
thor (0.19.1)
|
sucker_punch (2.0.3)
|
||||||
thread_safe (0.3.5)
|
concurrent-ruby (~> 1.0.0)
|
||||||
tilt (2.0.5)
|
thor (0.20.0)
|
||||||
tunemygc (1.0.68)
|
thread_safe (0.3.6)
|
||||||
tzinfo (1.2.2)
|
tilt (2.0.8)
|
||||||
|
timecop (0.9.1)
|
||||||
|
tunemygc (1.0.69)
|
||||||
|
tzinfo (1.2.4)
|
||||||
thread_safe (~> 0.1)
|
thread_safe (~> 0.1)
|
||||||
uglifier (3.0.2)
|
uglifier (3.2.0)
|
||||||
execjs (>= 0.3.0, < 3)
|
execjs (>= 0.3.0, < 3)
|
||||||
unicode-display_width (1.1.1)
|
unicode-display_width (1.3.0)
|
||||||
uservoice-ruby (0.0.11)
|
warden (1.2.7)
|
||||||
ezcrypto (>= 0.7.2)
|
|
||||||
json (>= 1.7.5)
|
|
||||||
oauth (>= 0.4.7)
|
|
||||||
warden (1.2.6)
|
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
websocket-driver (0.6.4)
|
websocket-driver (0.6.5)
|
||||||
websocket-extensions (>= 0.1.0)
|
websocket-extensions (>= 0.1.0)
|
||||||
websocket-extensions (0.1.2)
|
websocket-extensions (0.1.2)
|
||||||
|
|
||||||
|
@ -277,48 +300,51 @@ PLATFORMS
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
active_model_serializers
|
active_model_serializers
|
||||||
aws-sdk
|
aws-sdk (~> 2.7.0)
|
||||||
best_in_place
|
best_in_place
|
||||||
better_errors
|
better_errors
|
||||||
binding_of_caller
|
binding_of_caller
|
||||||
brakeman
|
brakeman
|
||||||
coffee-rails
|
|
||||||
delayed_job
|
delayed_job
|
||||||
delayed_job_active_record
|
delayed_job_active_record
|
||||||
devise
|
devise
|
||||||
doorkeeper
|
doorkeeper
|
||||||
dotenv-rails
|
dotenv-rails
|
||||||
exception_notification
|
exception_notification
|
||||||
factory_girl_rails
|
factory_bot_rails
|
||||||
|
faker
|
||||||
httparty
|
httparty
|
||||||
jquery-rails
|
jquery-rails
|
||||||
jquery-ui-rails
|
jquery-ui-rails
|
||||||
json
|
json
|
||||||
json-schema
|
json-schema
|
||||||
kaminari
|
kaminari
|
||||||
|
mailboxer
|
||||||
paperclip
|
paperclip
|
||||||
pg
|
pg
|
||||||
pry-byebug
|
pry-byebug
|
||||||
pry-rails
|
pry-rails
|
||||||
|
puma
|
||||||
pundit
|
pundit
|
||||||
pundit_extra
|
pundit_extra
|
||||||
rack-attack
|
rack-attack
|
||||||
rack-cors
|
rack-cors
|
||||||
rails (~> 5.0.0)
|
rails (~> 5.0.0)
|
||||||
redis
|
redis (~> 3.3.3)
|
||||||
rspec-rails
|
rspec-rails
|
||||||
rubocop
|
rubocop (~> 0.48.1)
|
||||||
sass-rails
|
sass-rails
|
||||||
shoulda-matchers
|
shoulda-matchers
|
||||||
simplecov
|
simplecov
|
||||||
slack-notifier
|
slack-notifier
|
||||||
snorlax
|
snorlax
|
||||||
|
sucker_punch
|
||||||
|
timecop
|
||||||
tunemygc
|
tunemygc
|
||||||
uglifier
|
uglifier
|
||||||
uservoice-ruby
|
|
||||||
|
|
||||||
RUBY VERSION
|
RUBY VERSION
|
||||||
ruby 2.3.0p0
|
ruby 2.3.0p0
|
||||||
|
|
||||||
BUNDLED WITH
|
BUNDLED WITH
|
||||||
1.13.2
|
1.16.1
|
||||||
|
|
2
Procfile
2
Procfile
|
@ -1,3 +1,3 @@
|
||||||
web: bundle exec rails server -p $PORT
|
web: bundle exec puma -p $PORT
|
||||||
worker: bundle exec rake jobs:work
|
worker: bundle exec rake jobs:work
|
||||||
|
|
||||||
|
|
69
README.md
69
README.md
|
@ -2,58 +2,45 @@ Metamaps
|
||||||
=======
|
=======
|
||||||
|
|
||||||
[](https://travis-ci.org/metamaps/metamaps)
|
[](https://travis-ci.org/metamaps/metamaps)
|
||||||
|
[](https://codeclimate.com/github/metamaps/metamaps)
|
||||||
|
|
||||||
## What is Metamaps?
|
## What is Metamaps?
|
||||||
|
|
||||||
Metamaps is a free and open source technology for changemakers, innovators, educators and students. It enables individuals and communities to build and visualize their shared knowledge and unlock their collective intelligence.
|
Metamaps is a free and open-source technology for changemakers, innovators, educators and students. It enables individuals and communities to build and visualize their shared knowledge and unlock their collective intelligence.
|
||||||
|
|
||||||
You can find a version of this software running at [metamaps.cc][site-beta], where the technology is being tested in a private beta.
|
You can find a version of this software running at [metamaps.cc][site-beta], where the technology is being tested in an open beta.
|
||||||
|
|
||||||
Metamaps is created and maintained by a distributed, nomadic community comprised of technologists, artists and storytellers. You can get in touch by using whichever of these channels you prefer:
|
Metamaps is developed and maintained by a distributed, nomadic community comprised of technologists, artists and storytellers. You can get in touch by using whichever of these channels you prefer:
|
||||||
|
|
||||||
## Community
|
## How do I learn more?
|
||||||
|
|
||||||
- To send us a personal message or request an invite to the open beta, get in touch with us at team@metamaps.cc or @metamapps on Twitter.
|
- Contact: [team@metamaps.cc](mailto:team@metamaps.cc) or [@metamapps](https://twitter.com/metamapps) on Twitter
|
||||||
|
- User Documentation: [docs.metamaps.cc](https://docs.metamaps.cc)
|
||||||
|
- User Community: [hylo.com/c/metamaps](https://www.hylo.com/c/metamaps)
|
||||||
|
- To see what we're developing, or to weigh in on what you'd like to see developed, see our [Metamaps Feedback and Features](https://trello.com/b/uFOA6a2x/metamaps-feedback-feature-ideas-requests) board on trello
|
||||||
|
- To follow along with, or contribute,to our design process, see our [Metamaps Design](https://trello.com/b/8HlCikOX/metamaps-design) board on trello
|
||||||
|
- To follow along with, or contribute to, our development process, see our [Github Issues and Pull Requests](https://github.com/metamaps/metamaps/issues)
|
||||||
|
- Request an invite to the open beta [here](https://metamaps.cc/request)
|
||||||
|
|
||||||
|
<!-- markdown hack to split two lists -->
|
||||||
|
|
||||||
|
- To send us a personal message get in touch with us via email, Twitter, or Hylo
|
||||||
- If you would like to report a bug, please check the [issues][contributing-issues] section in our [contributing instructions][contributing].
|
- If you would like to report a bug, please check the [issues][contributing-issues] section in our [contributing instructions][contributing].
|
||||||
- If you would like to get set up as a developer, that's great! Read on for help getting your development environment set up.
|
- If you would like to get set up as a developer, that's great! Read on for help getting your development environment set up.
|
||||||
|
|
||||||
## Installation
|
## 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!
|
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.
|
||||||
```
|
|
||||||
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.
|
|
||||||
|
|
||||||
To start servers which will run metamaps you can then run:
|
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]
|
||||||
./bin/start
|
- [Ubuntu Install Walkthrough][ubuntu-installation]
|
||||||
```
|
|
||||||
To stop them:
|
|
||||||
```
|
|
||||||
./bin/stop
|
|
||||||
```
|
|
||||||
With your webservers running, open a web browser and go to `http://localhost:3000`
|
|
||||||
|
|
||||||
You can sign in with the default account
|
If you prefer to isolate your install in a virtual machine, you may find it simpler to setup using Vagrant:
|
||||||
email: `user@user.com`
|
- [Vagrant installation][vagrant-installation]
|
||||||
password: `toolsplusconsciousness`
|
|
||||||
OR create a new account at `/join`, and use access code `qwertyui`
|
|
||||||
|
|
||||||
Start mapping and programming!
|
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]
|
||||||
We haven't set up instructions for using Vagrant on Windows, but there are instructions for a manual setup here:
|
|
||||||
|
|
||||||
- [For Windows][windows-installation]
|
|
||||||
|
|
||||||
## Contributing guidelines
|
|
||||||
|
|
||||||
Cloning this repository directly is primarily for those wishing to contribute to our codebase. Check out our [contributing instructions][contributing] to get involved.
|
|
||||||
|
|
||||||
## Licensing information
|
## Licensing information
|
||||||
|
|
||||||
|
@ -63,11 +50,13 @@ This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
|
||||||
The license can be read [here][license].
|
The license can be read [here][license].
|
||||||
|
|
||||||
Copyright (c) 2016 Connor Turland
|
Copyright (c) 2017 Connor Turland
|
||||||
|
|
||||||
[site-blog]: http://blog.metamaps.cc
|
|
||||||
[site-beta]: http://metamaps.cc
|
[site-beta]: http://metamaps.cc
|
||||||
[license]: https://github.com/metamaps/metamaps/blob/develop/LICENSE
|
[license]: https://github.com/metamaps/metamaps/blob/develop/LICENSE
|
||||||
[contributing]: https://github.com/metamaps/metamaps/blob/develop/doc/CONTRIBUTING.md
|
[contributing]: https://github.com/metamaps/metamaps/blob/develop/doc/CONTRIBUTING.md
|
||||||
[contributing-issues]: https://github.com/metamaps/metamaps/blob/develop/doc/CONTRIBUTING.md#reporting-bugs-and-other-issues
|
[contributing-issues]: https://github.com/metamaps/metamaps/blob/develop/doc/CONTRIBUTING.md#reporting-bugs-and-other-issues
|
||||||
|
[mac-installation]: https://github.com/metamaps/metamaps/blob/develop/doc/MacInstallation.md
|
||||||
|
[ubuntu-installation]: https://github.com/metamaps/metamaps/blob/develop/doc/UbuntuInstallation.md
|
||||||
|
[vagrant-installation]: https://github.com/metamaps/metamaps/blob/develop/doc/VagrantInstallation.md
|
||||||
[windows-installation]: https://github.com/metamaps/metamaps/blob/develop/doc/WindowsInstallation.md
|
[windows-installation]: https://github.com/metamaps/metamaps/blob/develop/doc/WindowsInstallation.md
|
||||||
|
|
1
Rakefile
Normal file → Executable file
1
Rakefile
Normal file → Executable file
|
@ -1,5 +1,6 @@
|
||||||
#!/usr/bin/env rake
|
#!/usr/bin/env rake
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
# Add your own tasks in files placed in lib/tasks ending in .rake,
|
||||||
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
|
||||||
|
|
||||||
|
|
2
Vagrantfile
vendored
2
Vagrantfile
vendored
|
@ -37,7 +37,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config|
|
||||||
config.vm.box = 'trusty64'
|
config.vm.box = 'trusty64'
|
||||||
config.vm.box_url = 'http://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box'
|
config.vm.box_url = 'http://cloud-images.ubuntu.com/vagrant/trusty/current/trusty-server-cloudimg-amd64-vagrant-disk1.box'
|
||||||
config.vm.network :forwarded_port, guest: 3000, host: 3000
|
config.vm.network :forwarded_port, guest: 3000, host: 3000
|
||||||
config.vm.network :forwarded_port, guest: 5001, host: 5001
|
config.vm.network :forwarded_port, guest: 5000, host: 5000
|
||||||
config.vm.network 'private_network', ip: '10.0.1.11'
|
config.vm.network 'private_network', ip: '10.0.1.11'
|
||||||
config.vm.synced_folder '.', '/vagrant', nfs: true
|
config.vm.synced_folder '.', '/vagrant', nfs: true
|
||||||
|
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
// eslint-disable spaced-comment
|
||||||
// JS and CSS bundles
|
// JS and CSS bundles
|
||||||
//= link_directory ../javascripts .js
|
//= link_directory ../javascripts .js
|
||||||
//= link_directory ../stylesheets .css
|
//= link_directory ../stylesheets .css
|
||||||
|
|
BIN
app/assets/images/.DS_Store
vendored
BIN
app/assets/images/.DS_Store
vendored
Binary file not shown.
Binary file not shown.
Before ![]() (image error) Size: 543 B |
Binary file not shown.
Before ![]() (image error) Size: 325 B |
BIN
app/assets/images/junto.gif
Normal file
BIN
app/assets/images/junto.gif
Normal file
Binary file not shown.
After ![]() (image error) Size: 30 KiB |
BIN
app/assets/images/metadata.png
Normal file
BIN
app/assets/images/metadata.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 1.5 KiB |
BIN
app/assets/images/metamaps-intro-poster.webp
Normal file
BIN
app/assets/images/metamaps-intro-poster.webp
Normal file
Binary file not shown.
After ![]() (image error) Size: 32 KiB |
Binary file not shown.
Before ![]() (image error) Size: 7.2 KiB After ![]() (image error) Size: 3.4 KiB ![]() ![]() |
BIN
app/assets/images/user_sprite.png
Executable file → Normal file
BIN
app/assets/images/user_sprite.png
Executable file → Normal file
Binary file not shown.
Before ![]() (image error) Size: 1.9 KiB After ![]() (image error) Size: 2.6 KiB ![]() ![]() |
BIN
app/assets/images/view-only.png
Normal file
BIN
app/assets/images/view-only.png
Normal file
Binary file not shown.
After ![]() (image error) Size: 421 B |
21
app/assets/javascripts/Metamaps.ServerData.js.erb
Normal file
21
app/assets/javascripts/Metamaps.ServerData.js.erb
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
/* global Metamaps */
|
||||||
|
|
||||||
|
/* erb variables from rails */
|
||||||
|
Metamaps.ServerData = Metamaps.ServerData || {}
|
||||||
|
Metamaps.ServerData['junto_spinner_darkgrey.gif'] = '<%= asset_path('junto_spinner_darkgrey.gif') %>'
|
||||||
|
Metamaps.ServerData['user.png'] = '<%= asset_path('user.png') %>'
|
||||||
|
Metamaps.ServerData['icons/wildcard.png'] = '<%= asset_path('icons/wildcard.png') %>'
|
||||||
|
Metamaps.ServerData['topic_description_signifier.png'] = '<%= asset_path('topic_description_signifier.png') %>'
|
||||||
|
Metamaps.ServerData['topic_link_signifier.png'] = '<%= asset_path('topic_link_signifier.png') %>'
|
||||||
|
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'] %>'
|
||||||
|
Metamaps.ServerData.VERSION = '<%= METAMAPS_VERSION %>'
|
||||||
|
Metamaps.ServerData.BUILD = '<%= METAMAPS_BUILD %>'
|
||||||
|
Metamaps.ServerData.LAST_UPDATED = '<%= METAMAPS_LAST_UPDATED %>'
|
23
app/assets/javascripts/application-secret.js
Normal file
23
app/assets/javascripts/application-secret.js
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
// This is a manifest file that'll be compiled into application.js, which will include all the files
|
||||||
|
// listed below.
|
||||||
|
//
|
||||||
|
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
|
||||||
|
// or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
|
||||||
|
//
|
||||||
|
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
|
||||||
|
// the compiled file.
|
||||||
|
//
|
||||||
|
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
||||||
|
// GO AFTER THE REQUIRES BELOW.
|
||||||
|
//
|
||||||
|
/* eslint-disable spaced-comment */
|
||||||
|
//= require jquery
|
||||||
|
//= require jquery-ui
|
||||||
|
//= require jquery_ujs
|
||||||
|
//= require action_cable
|
||||||
|
//= require_directory ./lib
|
||||||
|
//= require ./cloudcarousel-secret
|
||||||
|
//= require ./metamaps.secret.bundle
|
||||||
|
//= require ./Metamaps.ServerData
|
||||||
|
//= require homepageVimeoFallback
|
||||||
|
/* eslint-enable spaced-comment */
|
|
@ -10,10 +10,13 @@
|
||||||
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
// WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
|
||||||
// GO AFTER THE REQUIRES BELOW.
|
// GO AFTER THE REQUIRES BELOW.
|
||||||
//
|
//
|
||||||
|
/* eslint-disable spaced-comment */
|
||||||
//= require jquery
|
//= require jquery
|
||||||
//= require jquery-ui
|
//= require jquery-ui
|
||||||
//= require jquery_ujs
|
//= require jquery_ujs
|
||||||
|
//= require action_cable
|
||||||
//= require_directory ./lib
|
//= require_directory ./lib
|
||||||
//= require ./src/Metamaps.Erb
|
|
||||||
//= require ./webpacked/metamaps.bundle
|
//= require ./webpacked/metamaps.bundle
|
||||||
//= require ./src/check-canvas-support
|
//= require ./Metamaps.ServerData
|
||||||
|
//= require homepageVimeoFallback
|
||||||
|
/* eslint-enable spaced-comment */
|
||||||
|
|
438
app/assets/javascripts/cloudcarousel-secret.js
Normal file
438
app/assets/javascripts/cloudcarousel-secret.js
Normal file
|
@ -0,0 +1,438 @@
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
// CloudCarousel V1.0.5
|
||||||
|
// (c) 2011 by R Cecco. <http://www.professorcloud.com>
|
||||||
|
// MIT License
|
||||||
|
//
|
||||||
|
// Reflection code based on plugin by Christophe Beyls <http://www.digitalia.be>
|
||||||
|
//
|
||||||
|
// Please retain this copyright header in all versions of the software
|
||||||
|
//////////////////////////////////////////////////////////////////////////////////
|
||||||
|
var matched, browser;
|
||||||
|
|
||||||
|
jQuery.uaMatch = function( ua ) {
|
||||||
|
ua = ua.toLowerCase();
|
||||||
|
|
||||||
|
var match = /(chrome)[ \/]([\w.]+)/.exec( ua ) ||
|
||||||
|
/(webkit)[ \/]([\w.]+)/.exec( ua ) ||
|
||||||
|
/(opera)(?:.*version|)[ \/]([\w.]+)/.exec( ua ) ||
|
||||||
|
/(msie) ([\w.]+)/.exec( ua ) ||
|
||||||
|
ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec( ua ) ||
|
||||||
|
[];
|
||||||
|
|
||||||
|
return {
|
||||||
|
browser: match[ 1 ] || "",
|
||||||
|
version: match[ 2 ] || "0"
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
matched = jQuery.uaMatch( navigator.userAgent );
|
||||||
|
browser = {};
|
||||||
|
|
||||||
|
if ( matched.browser ) {
|
||||||
|
browser[ matched.browser ] = true;
|
||||||
|
browser.version = matched.version;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chrome is Webkit, but Webkit is also Safari.
|
||||||
|
if ( browser.chrome ) {
|
||||||
|
browser.webkit = true;
|
||||||
|
} else if ( browser.webkit ) {
|
||||||
|
browser.safari = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
jQuery.browser = browser;
|
||||||
|
|
||||||
|
(function($) {
|
||||||
|
|
||||||
|
// START Reflection object.
|
||||||
|
// Creates a reflection for underneath an image.
|
||||||
|
// IE uses an image with IE specific filter properties, other browsers use the Canvas tag.
|
||||||
|
// The position and size of the reflection gets updated by updateAll() in Controller.
|
||||||
|
function Reflection(img, reflHeight, opacity) {
|
||||||
|
|
||||||
|
var reflection, cntx, imageWidth = img.width, imageHeight = img.width, gradient, parent;
|
||||||
|
|
||||||
|
parent = $(img.parentNode);
|
||||||
|
this.element = reflection = parent.append("<canvas class='reflection' style='position:absolute'/>").find(':last')[0];
|
||||||
|
if ( !reflection.getContext && $.browser.msie) {
|
||||||
|
this.element = reflection = parent.append("<img class='reflection' style='position:absolute'/>").find(':last')[0];
|
||||||
|
reflection.src = img.src;
|
||||||
|
reflection.style.filter = "flipv progid:DXImageTransform.Microsoft.Alpha(opacity=" + (opacity * 100) + ", style=1, finishOpacity=0, startx=0, starty=0, finishx=0, finishy=" + (reflHeight / imageHeight * 100) + ")";
|
||||||
|
|
||||||
|
} else {
|
||||||
|
cntx = reflection.getContext("2d");
|
||||||
|
try {
|
||||||
|
|
||||||
|
|
||||||
|
$(reflection).attr({width: imageWidth, height: reflHeight});
|
||||||
|
cntx.save();
|
||||||
|
cntx.translate(0, imageHeight-1);
|
||||||
|
cntx.scale(1, -1);
|
||||||
|
cntx.drawImage(img, 0, 0, imageWidth, imageHeight);
|
||||||
|
cntx.restore();
|
||||||
|
cntx.globalCompositeOperation = "destination-out";
|
||||||
|
gradient = cntx.createLinearGradient(0, 0, 0, reflHeight);
|
||||||
|
gradient.addColorStop(0, "rgba(255, 255, 255, " + (1 - opacity) + ")");
|
||||||
|
gradient.addColorStop(1, "rgba(255, 255, 255, 1.0)");
|
||||||
|
cntx.fillStyle = gradient;
|
||||||
|
cntx.fillRect(0, 0, imageWidth, reflHeight);
|
||||||
|
} catch(e) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
// Store a copy of the alt and title attrs into the reflection
|
||||||
|
$(reflection).attr({ 'alt': $(img).attr('alt'), title: $(img).attr('title')} );
|
||||||
|
|
||||||
|
} //END Reflection object
|
||||||
|
|
||||||
|
// START Item object.
|
||||||
|
// A wrapper object for items within the carousel.
|
||||||
|
var Item = function(imgIn, options)
|
||||||
|
{
|
||||||
|
this.orgWidth = imgIn.width;
|
||||||
|
this.orgHeight = imgIn.height;
|
||||||
|
this.image = imgIn;
|
||||||
|
this.reflection = null;
|
||||||
|
this.alt = imgIn.alt;
|
||||||
|
this.title = imgIn.title;
|
||||||
|
this.imageOK = false;
|
||||||
|
this.options = options;
|
||||||
|
|
||||||
|
this.imageOK = true;
|
||||||
|
|
||||||
|
if (this.options.reflHeight > 0)
|
||||||
|
{
|
||||||
|
this.reflection = new Reflection(this.image, this.options.reflHeight, this.options.reflOpacity);
|
||||||
|
}
|
||||||
|
$(this.image).css('position','absolute'); // Bizarre. This seems to reset image width to 0 on webkit!
|
||||||
|
};// END Item object
|
||||||
|
|
||||||
|
|
||||||
|
// Controller object.
|
||||||
|
// This handles moving all the items, dealing with mouse clicks etc.
|
||||||
|
var Controller = function(container, images, options)
|
||||||
|
{
|
||||||
|
var items = [], funcSin = Math.sin, funcCos = Math.cos, ctx=this;
|
||||||
|
this.controlTimer = 0;
|
||||||
|
this.stopped = false;
|
||||||
|
//this.imagesLoaded = 0;
|
||||||
|
this.container = container;
|
||||||
|
this.xRadius = options.xRadius;
|
||||||
|
this.yRadius = options.yRadius;
|
||||||
|
this.showFrontTextTimer = 0;
|
||||||
|
this.autoRotateTimer = 0;
|
||||||
|
if (options.xRadius === 0)
|
||||||
|
{
|
||||||
|
this.xRadius = ($(container).width()/2.3);
|
||||||
|
}
|
||||||
|
if (options.yRadius === 0)
|
||||||
|
{
|
||||||
|
this.yRadius = ($(container).height()/6);
|
||||||
|
}
|
||||||
|
|
||||||
|
this.xCentre = options.xPos;
|
||||||
|
this.yCentre = options.yPos;
|
||||||
|
this.frontIndex = 0; // Index of the item at the front
|
||||||
|
|
||||||
|
// Start with the first item at the front.
|
||||||
|
this.rotation = this.destRotation = Math.PI/2;
|
||||||
|
this.timeDelay = 1000/options.FPS;
|
||||||
|
|
||||||
|
// Turn on the infoBox
|
||||||
|
if(options.altBox !== null)
|
||||||
|
{
|
||||||
|
$(options.altBox).css('display','block');
|
||||||
|
$(options.titleBox).css('display','block');
|
||||||
|
}
|
||||||
|
// Turn on relative position for container to allow absolutely positioned elements
|
||||||
|
// within it to work.
|
||||||
|
$(container).css({ position:'relative', overflow:'hidden'} );
|
||||||
|
|
||||||
|
$(options.buttonLeft).css('display','inline');
|
||||||
|
$(options.buttonRight).css('display','inline');
|
||||||
|
|
||||||
|
// Setup the buttons.
|
||||||
|
$(options.buttonLeft).bind('mouseup',this,function(event){
|
||||||
|
event.data.rotate(-1);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
$(options.buttonRight).bind('mouseup',this,function(event){
|
||||||
|
event.data.rotate(1);
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
// START METAMAPS CODE
|
||||||
|
// Add code that makes tab and shift+tab scroll through metacodes
|
||||||
|
$('.new_topic').bind('keydown',this,function(event){
|
||||||
|
if (event.keyCode == 9 && event.shiftKey) {
|
||||||
|
$(container).show()
|
||||||
|
event.data.rotate(-1);
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
} else if (event.keyCode == 9) {
|
||||||
|
$(container).show()
|
||||||
|
event.data.rotate(1);
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// END METAMAPS CODE
|
||||||
|
|
||||||
|
// You will need this plugin for the mousewheel to work: http://plugins.jquery.com/project/mousewheel
|
||||||
|
if (options.mouseWheel)
|
||||||
|
{
|
||||||
|
// START METAMAPS CODE
|
||||||
|
/*$('body').bind('mousewheel',this,function(event, delta) {
|
||||||
|
if (Metamaps.Create.newTopic.beingCreated &&
|
||||||
|
!Metamaps.Create.isSwitchingSet &&
|
||||||
|
!Metamaps.Create.newTopic.pinned) {
|
||||||
|
event.data.rotate(delta);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});*/
|
||||||
|
// END METAMAPS CODE
|
||||||
|
// ORIGINAL CODE
|
||||||
|
// $(container).bind('mousewheel',this,function(event, delta) {
|
||||||
|
// event.data.rotate(delta);
|
||||||
|
// return false;
|
||||||
|
// });
|
||||||
|
//
|
||||||
|
}
|
||||||
|
$(container).unbind('mouseover click').bind('mouseover click',this,function(event){
|
||||||
|
|
||||||
|
clearInterval(event.data.autoRotateTimer); // Stop auto rotation if mouse over.
|
||||||
|
var text = $(event.target).attr('alt');
|
||||||
|
// If we have moved over a carousel item, then show the alt and title text.
|
||||||
|
|
||||||
|
if ( text !== undefined && text !== null )
|
||||||
|
{
|
||||||
|
|
||||||
|
clearTimeout(event.data.showFrontTextTimer);
|
||||||
|
$(options.altBox).html( ($(event.target).attr('alt') ));
|
||||||
|
//$(options.titleBox).html( ($(event.target).attr('title') ));
|
||||||
|
if ( options.bringToFront && event.type == 'click' )
|
||||||
|
{
|
||||||
|
$(options.titleBox).html( ($(event.target).attr('title') ));
|
||||||
|
// START METAMAPS CODE
|
||||||
|
Metamaps.Create.newTopic.metacode = $(event.target).attr('data-id');
|
||||||
|
// END METAMAPS CODE
|
||||||
|
var idx = $(event.target).data('itemIndex');
|
||||||
|
var frontIndex = event.data.frontIndex;
|
||||||
|
//var diff = idx - frontIndex;
|
||||||
|
var diff = (idx - frontIndex) % images.length;
|
||||||
|
if (Math.abs(diff) > images.length / 2) {
|
||||||
|
diff += (diff > 0 ? -images.length : images.length);
|
||||||
|
}
|
||||||
|
|
||||||
|
event.data.rotate(-diff);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
// START METAMAPS CODE - initialize newTopic.metacode
|
||||||
|
var first = $(this.container).find('img').get(0)
|
||||||
|
Metamaps.Create.newTopic.metacode = $(first).data('id')
|
||||||
|
// END METAMAPS CODE
|
||||||
|
|
||||||
|
// If we have moved out of a carousel item (or the container itself),
|
||||||
|
// restore the text of the front item in 1 second.
|
||||||
|
$(container).bind('mouseout',this,function(event){
|
||||||
|
var context = event.data;
|
||||||
|
clearTimeout(context.showFrontTextTimer);
|
||||||
|
context.showFrontTextTimer = setTimeout( function(){context.showFrontText();},1000);
|
||||||
|
context.autoRotate(); // Start auto rotation.
|
||||||
|
});
|
||||||
|
|
||||||
|
// Prevent items from being selected as mouse is moved and clicked in the container.
|
||||||
|
$(container).bind('mousedown',this,function(event){
|
||||||
|
|
||||||
|
event.data.container.focus();
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
container.onselectstart = function () { return false; }; // For IE.
|
||||||
|
|
||||||
|
this.innerWrapper = $(container).wrapInner('<div style="position:absolute;width:100%;height:100%;"/>').children()[0];
|
||||||
|
|
||||||
|
// Shows the text from the front most item.
|
||||||
|
this.showFrontText = function()
|
||||||
|
{
|
||||||
|
if ( items[this.frontIndex] === undefined ) { return; } // Images might not have loaded yet.
|
||||||
|
// METAMAPS CODE
|
||||||
|
Metamaps.Create.newTopic.setMetacode($(items[this.frontIndex].image).attr('data-id'))
|
||||||
|
// NOT METAMAPS CODE
|
||||||
|
//$(options.titleBox).html( $(items[this.frontIndex].image).attr('title'));
|
||||||
|
//$(options.altBox).html( $(items[this.frontIndex].image).attr('alt'));
|
||||||
|
};
|
||||||
|
|
||||||
|
this.go = function()
|
||||||
|
{
|
||||||
|
if(this.controlTimer !== 0) { return; }
|
||||||
|
var context = this;
|
||||||
|
this.controlTimer = setTimeout( function(){context.updateAll();},this.timeDelay);
|
||||||
|
};
|
||||||
|
|
||||||
|
this.stop = function()
|
||||||
|
{
|
||||||
|
clearTimeout(this.controlTimer);
|
||||||
|
this.controlTimer = 0;
|
||||||
|
// METAMAPS CODE
|
||||||
|
$(container).hide()
|
||||||
|
// END METAMAPS CODE
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
// Starts the rotation of the carousel. Direction is the number (+-) of carousel items to rotate by.
|
||||||
|
this.rotate = function(direction)
|
||||||
|
{
|
||||||
|
this.frontIndex -= direction;
|
||||||
|
if (this.frontIndex == -1) this.frontIndex = items.length - 1;
|
||||||
|
this.frontIndex %= items.length;
|
||||||
|
this.destRotation += ( Math.PI / items.length ) * ( 2*direction );
|
||||||
|
this.showFrontText();
|
||||||
|
this.go();
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
this.autoRotate = function()
|
||||||
|
{
|
||||||
|
if ( options.autoRotate !== 'no' )
|
||||||
|
{
|
||||||
|
var dir = (options.autoRotate === 'right')? 1 : -1;
|
||||||
|
this.autoRotateTimer = setInterval( function(){ctx.rotate(dir); }, options.autoRotateDelay );
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// This is the main loop function that moves everything.
|
||||||
|
this.updateAll = function()
|
||||||
|
{
|
||||||
|
var minScale = options.minScale; // This is the smallest scale applied to the furthest item.
|
||||||
|
var smallRange = (1-minScale) * 0.5;
|
||||||
|
var w,h,x,y,scale,item,sinVal;
|
||||||
|
|
||||||
|
var change = (this.destRotation - this.rotation);
|
||||||
|
var absChange = Math.abs(change);
|
||||||
|
|
||||||
|
this.rotation += change * options.speed;
|
||||||
|
if ( absChange < 0.001 ) { this.rotation = this.destRotation; }
|
||||||
|
var itemsLen = items.length;
|
||||||
|
var spacing = (Math.PI / itemsLen) * 2;
|
||||||
|
//var wrapStyle = null;
|
||||||
|
var radians = this.rotation;
|
||||||
|
var isMSIE = $.browser.msie;
|
||||||
|
|
||||||
|
// Turn off display. This can reduce repaints/reflows when making style and position changes in the loop.
|
||||||
|
// See http://dev.opera.com/articles/view/efficient-javascript/?page=3
|
||||||
|
this.innerWrapper.style.display = 'none';
|
||||||
|
|
||||||
|
var style;
|
||||||
|
var px = 'px', reflHeight;
|
||||||
|
var context = this;
|
||||||
|
for (var i = 0; i<itemsLen ;i++)
|
||||||
|
{
|
||||||
|
item = items[i];
|
||||||
|
|
||||||
|
sinVal = funcSin(radians);
|
||||||
|
|
||||||
|
scale = ((sinVal+1) * smallRange) + minScale;
|
||||||
|
|
||||||
|
x = this.xCentre + (( (funcCos(radians) * this.xRadius) - (item.orgWidth*0.5)) * scale);
|
||||||
|
y = this.yCentre + (( (sinVal * this.yRadius) ) * scale);
|
||||||
|
|
||||||
|
if (item.imageOK)
|
||||||
|
{
|
||||||
|
var img = item.image;
|
||||||
|
|
||||||
|
img.style.zIndex = "" + (scale * 100)>>0; // >>0 = Math.foor(). Firefox doesn't like fractional decimals in z-index.
|
||||||
|
w = img.width = item.orgWidth * scale;
|
||||||
|
h = img.height = item.orgHeight * scale;
|
||||||
|
img.style.left = x + px ;
|
||||||
|
img.style.top = y + px;
|
||||||
|
if (item.reflection !== null)
|
||||||
|
{
|
||||||
|
reflHeight = options.reflHeight * scale;
|
||||||
|
style = item.reflection.element.style;
|
||||||
|
style.left = x + px;
|
||||||
|
style.top = y + h + options.reflGap * scale + px;
|
||||||
|
style.width = w + px;
|
||||||
|
if (isMSIE)
|
||||||
|
{
|
||||||
|
style.filter.finishy = (reflHeight / h * 100);
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
style.height = reflHeight + px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
radians += spacing;
|
||||||
|
}
|
||||||
|
// Turn display back on.
|
||||||
|
this.innerWrapper.style.display = 'block';
|
||||||
|
|
||||||
|
// If we have a preceptable change in rotation then loop again next frame.
|
||||||
|
if ( absChange >= 0.001 )
|
||||||
|
{
|
||||||
|
this.controlTimer = setTimeout( function(){context.updateAll();},this.timeDelay);
|
||||||
|
}else
|
||||||
|
{
|
||||||
|
// Otherwise just stop completely.
|
||||||
|
this.stop();
|
||||||
|
}
|
||||||
|
}; // END updateAll
|
||||||
|
|
||||||
|
// Create an Item object for each image
|
||||||
|
// func = function(){return;ctx.updateAll();} ;
|
||||||
|
|
||||||
|
// Check if images have loaded. We need valid widths and heights for the reflections.
|
||||||
|
this.checkImagesLoaded = function()
|
||||||
|
{
|
||||||
|
var i;
|
||||||
|
for(i=0;i<images.length;i++) {
|
||||||
|
if ( (images[i].width === undefined) || ( (images[i].complete !== undefined) && (!images[i].complete) ))
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for(i=0;i<images.length;i++) {
|
||||||
|
items.push( new Item( images[i], options ) );
|
||||||
|
$(images[i]).data('itemIndex',i);
|
||||||
|
}
|
||||||
|
// If all images have valid widths and heights, we can stop checking.
|
||||||
|
clearInterval(this.tt);
|
||||||
|
// METAMAPS COMMENT this.showFrontText();
|
||||||
|
this.autoRotate();
|
||||||
|
this.updateAll();
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
this.tt = setInterval( function(){ctx.checkImagesLoaded();},50);
|
||||||
|
}; // END Controller object
|
||||||
|
|
||||||
|
// The jQuery plugin part. Iterates through items specified in selector and inits a Controller class for each one.
|
||||||
|
$.fn.CloudCarousel = function(options) {
|
||||||
|
|
||||||
|
this.each( function() {
|
||||||
|
|
||||||
|
options = $.extend({}, {
|
||||||
|
reflHeight:0,
|
||||||
|
reflOpacity:0.5,
|
||||||
|
reflGap:0,
|
||||||
|
minScale:0.5,
|
||||||
|
xPos:0,
|
||||||
|
yPos:0,
|
||||||
|
xRadius:0,
|
||||||
|
yRadius:0,
|
||||||
|
altBox:null,
|
||||||
|
titleBox:null,
|
||||||
|
FPS: 30,
|
||||||
|
autoRotate: 'no',
|
||||||
|
autoRotateDelay: 1500,
|
||||||
|
speed:0.2,
|
||||||
|
mouseWheel: false,
|
||||||
|
bringToFront: false
|
||||||
|
},options );
|
||||||
|
// Create a Controller for each carousel.
|
||||||
|
$(this).data('cloudcarousel', new Controller( this, $('.cloudcarousel',$(this)), options) );
|
||||||
|
});
|
||||||
|
return this;
|
||||||
|
};
|
||||||
|
|
||||||
|
})(jQuery);
|
29
app/assets/javascripts/homepageVimeoFallback.js.erb
Normal file
29
app/assets/javascripts/homepageVimeoFallback.js.erb
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
/* global $ */
|
||||||
|
|
||||||
|
$(document).ready(function() {
|
||||||
|
if (window.location.pathname === '/') {
|
||||||
|
$.ajax({
|
||||||
|
type: 'GET',
|
||||||
|
url: 'https://i.vimeocdn.com/video/',
|
||||||
|
error: function(e) {
|
||||||
|
$('.homeVideo').hide()
|
||||||
|
$('.homeVideo').replaceWith($('<video/>', {
|
||||||
|
poster: '<%= asset_path('metamaps-intro-poster.webp') %>',
|
||||||
|
width: '560',
|
||||||
|
height: '315',
|
||||||
|
class: 'homeVideo',
|
||||||
|
controls: ''
|
||||||
|
}))
|
||||||
|
$('.homeVideo').append($('<source/>', {
|
||||||
|
src: 'https://metamaps.cc/videos/metamaps-intro.mp4',
|
||||||
|
type: 'video/mp4'
|
||||||
|
}))
|
||||||
|
$('.homeVideo').append(
|
||||||
|
'<p>You can watch our instruction video at ' +
|
||||||
|
'<a href="https://metamaps.cc/videos/metamaps-intro.mp4">' +
|
||||||
|
'https://metamaps.cc/videos/metamaps-intro.mp4</a>.'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}// if
|
||||||
|
})
|
Binary file not shown.
Binary file not shown.
161
app/assets/javascripts/lib/ajaxq.js
Normal file
161
app/assets/javascripts/lib/ajaxq.js
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
// AjaxQ jQuery Plugin
|
||||||
|
// Copyright (c) 2012 Foliotek Inc.
|
||||||
|
// MIT License
|
||||||
|
// https://github.com/Foliotek/ajaxq
|
||||||
|
// Uses CommonJS, AMD or browser globals to create a jQuery plugin.
|
||||||
|
|
||||||
|
(function (factory) {
|
||||||
|
if (typeof define === 'function' && define.amd) {
|
||||||
|
// AMD. Register as an anonymous module.
|
||||||
|
define(['jquery'], factory);
|
||||||
|
} else if (typeof module === 'object' && module.exports) {
|
||||||
|
// Node/CommonJS
|
||||||
|
module.exports = factory(require('jquery'));
|
||||||
|
} else {
|
||||||
|
// Browser globals
|
||||||
|
factory(jQuery);
|
||||||
|
}
|
||||||
|
}(function ($) {
|
||||||
|
var queues = {};
|
||||||
|
var activeReqs = {};
|
||||||
|
|
||||||
|
// Register an $.ajaxq function, which follows the $.ajax interface, but allows a queue name which will force only one request per queue to fire.
|
||||||
|
// opts can be the regular $.ajax settings plainObject, or a callback returning the settings object, to be evaluated just prior to the actual call to $.ajax.
|
||||||
|
$.ajaxq = function(qname, opts) {
|
||||||
|
|
||||||
|
if (typeof opts === "undefined") {
|
||||||
|
throw ("AjaxQ: queue name is not provided");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Will return a Deferred promise object extended with success/error/callback, so that this function matches the interface of $.ajax
|
||||||
|
var deferred = $.Deferred(),
|
||||||
|
promise = deferred.promise();
|
||||||
|
|
||||||
|
promise.success = promise.done;
|
||||||
|
promise.error = promise.fail;
|
||||||
|
promise.complete = promise.always;
|
||||||
|
|
||||||
|
// Check whether options are to be evaluated at call time or not.
|
||||||
|
var deferredOpts = typeof opts === 'function';
|
||||||
|
// Create a deep copy of the arguments, and enqueue this request.
|
||||||
|
var clonedOptions = !deferredOpts ? $.extend(true, {}, opts) : null;
|
||||||
|
enqueue(function() {
|
||||||
|
// Send off the ajax request now that the item has been removed from the queue
|
||||||
|
var jqXHR = $.ajax.apply(window, [deferredOpts ? opts() : clonedOptions]);
|
||||||
|
|
||||||
|
// Notify the returned deferred object with the correct context when the jqXHR is done or fails
|
||||||
|
// Note that 'always' will automatically be fired once one of these are called: http://api.jquery.com/category/deferred-object/.
|
||||||
|
jqXHR.done(function() {
|
||||||
|
deferred.resolve.apply(this, arguments);
|
||||||
|
});
|
||||||
|
jqXHR.fail(function() {
|
||||||
|
deferred.reject.apply(this, arguments);
|
||||||
|
});
|
||||||
|
|
||||||
|
jqXHR.always(dequeue); // make sure to dequeue the next request AFTER the done and fail callbacks are fired
|
||||||
|
|
||||||
|
return jqXHR;
|
||||||
|
});
|
||||||
|
|
||||||
|
return promise;
|
||||||
|
|
||||||
|
|
||||||
|
// If there is no queue, create an empty one and instantly process this item.
|
||||||
|
// Otherwise, just add this item onto it for later processing.
|
||||||
|
function enqueue(cb) {
|
||||||
|
if (!queues[qname]) {
|
||||||
|
queues[qname] = [];
|
||||||
|
var xhr = cb();
|
||||||
|
activeReqs[qname] = xhr;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
queues[qname].push(cb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove the next callback from the queue and fire it off.
|
||||||
|
// If the queue was empty (this was the last item), delete it from memory so the next one can be instantly processed.
|
||||||
|
function dequeue() {
|
||||||
|
if (!queues[qname]) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
var nextCallback = queues[qname].shift();
|
||||||
|
if (nextCallback) {
|
||||||
|
var xhr = nextCallback();
|
||||||
|
activeReqs[qname] = xhr;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
delete queues[qname];
|
||||||
|
delete activeReqs[qname];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// Register a $.postq and $.getq method to provide shortcuts for $.get and $.post
|
||||||
|
// Copied from jQuery source to make sure the functions share the same defaults as $.get and $.post.
|
||||||
|
$.each( [ "getq", "postq" ], function( i, method ) {
|
||||||
|
$[ method ] = function( qname, url, data, callback, type ) {
|
||||||
|
|
||||||
|
if ( $.isFunction( data ) ) {
|
||||||
|
type = type || callback;
|
||||||
|
callback = data;
|
||||||
|
data = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
return $.ajaxq(qname, {
|
||||||
|
type: method === "postq" ? "post" : "get",
|
||||||
|
url: url,
|
||||||
|
data: data,
|
||||||
|
success: callback,
|
||||||
|
dataType: type
|
||||||
|
});
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
var isQueueRunning = function(qname) {
|
||||||
|
return (queues.hasOwnProperty(qname) && queues[qname].length > 0) || activeReqs.hasOwnProperty(qname);
|
||||||
|
};
|
||||||
|
|
||||||
|
var isAnyQueueRunning = function() {
|
||||||
|
for (var i in queues) {
|
||||||
|
if (isQueueRunning(i)) return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
$.ajaxq.isRunning = function(qname) {
|
||||||
|
if (qname) return isQueueRunning(qname);
|
||||||
|
else return isAnyQueueRunning();
|
||||||
|
};
|
||||||
|
|
||||||
|
$.ajaxq.getActiveRequest = function(qname) {
|
||||||
|
if (!qname) throw ("AjaxQ: queue name is required");
|
||||||
|
|
||||||
|
return activeReqs[qname];
|
||||||
|
};
|
||||||
|
|
||||||
|
$.ajaxq.abort = function(qname) {
|
||||||
|
if (!qname) throw ("AjaxQ: queue name is required");
|
||||||
|
|
||||||
|
var current = $.ajaxq.getActiveRequest(qname);
|
||||||
|
delete queues[qname];
|
||||||
|
delete activeReqs[qname];
|
||||||
|
if (current) current.abort();
|
||||||
|
};
|
||||||
|
|
||||||
|
$.ajaxq.clear = function(qname) {
|
||||||
|
if (!qname) {
|
||||||
|
for (var i in queues) {
|
||||||
|
if (queues.hasOwnProperty(i)) {
|
||||||
|
queues[i] = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (queues[qname]) {
|
||||||
|
queues[qname] = [];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
}));
|
|
@ -1,39 +0,0 @@
|
||||||
var attachMediaStream = function (stream, el, options) {
|
|
||||||
var URL = window.URL;
|
|
||||||
var opts = {
|
|
||||||
autoplay: true,
|
|
||||||
mirror: false,
|
|
||||||
muted: false
|
|
||||||
};
|
|
||||||
var element = el || document.createElement('video');
|
|
||||||
var item;
|
|
||||||
|
|
||||||
if (options) {
|
|
||||||
for (item in options) {
|
|
||||||
opts[item] = options[item];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (opts.autoplay) element.autoplay = 'autoplay';
|
|
||||||
if (opts.muted) element.muted = true;
|
|
||||||
if (opts.mirror) {
|
|
||||||
['', 'moz', 'webkit', 'o', 'ms'].forEach(function (prefix) {
|
|
||||||
var styleName = prefix ? prefix + 'Transform' : 'transform';
|
|
||||||
element.style[styleName] = 'scaleX(-1)';
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
// this first one should work most everywhere now
|
|
||||||
// but we have a few fallbacks just in case.
|
|
||||||
if (URL && URL.createObjectURL) {
|
|
||||||
element.src = URL.createObjectURL(stream);
|
|
||||||
} else if (element.srcObject) {
|
|
||||||
element.srcObject = stream;
|
|
||||||
} else if (element.mozSrcObject) {
|
|
||||||
element.mozSrcObject = stream;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
return element;
|
|
||||||
};
|
|
2
app/assets/javascripts/lib/canvas-to-blob.min.js
vendored
Normal file
2
app/assets/javascripts/lib/canvas-to-blob.min.js
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
!function(t){"use strict";var e=t.HTMLCanvasElement&&t.HTMLCanvasElement.prototype,o=t.Blob&&function(){try{return Boolean(new Blob)}catch(t){return!1}}(),n=o&&t.Uint8Array&&function(){try{return 100===new Blob([new Uint8Array(100)]).size}catch(t){return!1}}(),r=t.BlobBuilder||t.WebKitBlobBuilder||t.MozBlobBuilder||t.MSBlobBuilder,a=/^data:((.*?)(;charset=.*?)?)(;base64)?,/,i=(o||r)&&t.atob&&t.ArrayBuffer&&t.Uint8Array&&function(t){var e,i,l,u,b,c,d,B,f;if(e=t.match(a),!e)throw new Error("invalid data URI");for(i=e[2]?e[1]:"text/plain"+(e[3]||";charset=US-ASCII"),l=!!e[4],u=t.slice(e[0].length),b=l?atob(u):decodeURIComponent(u),c=new ArrayBuffer(b.length),d=new Uint8Array(c),B=0;B<b.length;B+=1)d[B]=b.charCodeAt(B);return o?new Blob([n?d:c],{type:i}):(f=new r,f.append(c),f.getBlob(i))};t.HTMLCanvasElement&&!e.toBlob&&(e.mozGetAsFile?e.toBlob=function(t,o,n){t(n&&e.toDataURL&&i?i(this.toDataURL(o,n)):this.mozGetAsFile("blob",o))}:e.toDataURL&&i&&(e.toBlob=function(t,e,o){t(i(this.toDataURL(e,o)))})),"function"==typeof define&&define.amd?define(function(){return i}):"object"==typeof module&&module.exports?module.exports=i:t.dataURLtoBlob=i}(window);
|
||||||
|
//# sourceMappingURL=canvas-to-blob.min.js.map
|
|
@ -161,40 +161,43 @@ jQuery.browser = browser;
|
||||||
return false;
|
return false;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// START METAMAPS CODE
|
||||||
// Add code that makes tab and shift+tab scroll through metacodes
|
// Add code that makes tab and shift+tab scroll through metacodes
|
||||||
$('.new_topic').bind('keydown',this,function(event){
|
$('.new_topic').bind('keydown',this,function(event){
|
||||||
if (event.keyCode == 9 && event.shiftKey) {
|
if (event.keyCode == 9) {
|
||||||
event.data.rotate(-1);
|
if (event.shiftKey) {
|
||||||
event.preventDefault();
|
event.data.rotate(-1)
|
||||||
event.stopPropagation();
|
} else {
|
||||||
} else if (event.keyCode == 9) {
|
event.data.rotate(1)
|
||||||
event.data.rotate(1);
|
}
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
}
|
Metamaps.Create.newTopic.metacode = $(items[event.data.frontIndex].image).attr('data-id');
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
// END METAMAPS CODE
|
||||||
|
|
||||||
// You will need this plugin for the mousewheel to work: http://plugins.jquery.com/project/mousewheel
|
// You will need this plugin for the mousewheel to work: http://plugins.jquery.com/project/mousewheel
|
||||||
if (options.mouseWheel)
|
if (options.mouseWheel)
|
||||||
{
|
{
|
||||||
// START METAMAPS CODE
|
// START METAMAPS CODE
|
||||||
$('body').bind('mousewheel',this,function(event, delta) {
|
$('body').bind('mousewheel',this,function(event, delta) {
|
||||||
if (Metamaps.Create.newTopic.beingCreated &&
|
if (Metamaps.Create.newTopic.beingCreated &&
|
||||||
!Metamaps.Create.isSwitchingSet &&
|
!Metamaps.Create.isSwitchingSet &&
|
||||||
!Metamaps.Create.newTopic.pinned) {
|
!Metamaps.Create.newTopic.pinned) {
|
||||||
event.data.rotate(delta);
|
event.data.rotate(delta);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
// END METAMAPS CODE
|
// END METAMAPS CODE
|
||||||
/* ORIGINAL CODE
|
// ORIGINAL CODE
|
||||||
$(container).bind('mousewheel',this,function(event, delta) {
|
// $(container).bind('mousewheel',this,function(event, delta) {
|
||||||
event.data.rotate(delta);
|
// event.data.rotate(delta);
|
||||||
return false;
|
// return false;
|
||||||
});
|
// });
|
||||||
*/
|
//
|
||||||
}
|
}
|
||||||
$(container).bind('mouseover click',this,function(event){
|
$(container).unbind('mouseover click').bind('mouseover click',this,function(event){
|
||||||
|
|
||||||
clearInterval(event.data.autoRotateTimer); // Stop auto rotation if mouse over.
|
clearInterval(event.data.autoRotateTimer); // Stop auto rotation if mouse over.
|
||||||
var text = $(event.target).attr('alt');
|
var text = $(event.target).attr('alt');
|
||||||
|
@ -208,22 +211,27 @@ jQuery.browser = browser;
|
||||||
//$(options.titleBox).html( ($(event.target).attr('title') ));
|
//$(options.titleBox).html( ($(event.target).attr('title') ));
|
||||||
if ( options.bringToFront && event.type == 'click' )
|
if ( options.bringToFront && event.type == 'click' )
|
||||||
{
|
{
|
||||||
$(options.titleBox).html( ($(event.target).attr('title') ));
|
$(options.titleBox).html( ($(event.target).attr('title') ));
|
||||||
// METAMAPS CODE
|
// START METAMAPS CODE
|
||||||
Metamaps.Create.newTopic.metacode = $(event.target).attr('data-id');
|
Metamaps.Create.newTopic.metacode = $(event.target).attr('data-id');
|
||||||
// NOT METAMAPS CODE
|
// END METAMAPS CODE
|
||||||
var idx = $(event.target).data('itemIndex');
|
var idx = $(event.target).data('itemIndex');
|
||||||
var frontIndex = event.data.frontIndex;
|
var frontIndex = event.data.frontIndex;
|
||||||
//var diff = idx - frontIndex;
|
//var diff = idx - frontIndex;
|
||||||
var diff = (idx - frontIndex) % images.length;
|
var diff = (idx - frontIndex) % images.length;
|
||||||
if (Math.abs(diff) > images.length / 2) {
|
if (Math.abs(diff) > images.length / 2) {
|
||||||
diff += (diff > 0 ? -images.length : images.length);
|
diff += (diff > 0 ? -images.length : images.length);
|
||||||
}
|
}
|
||||||
|
|
||||||
event.data.rotate(-diff);
|
event.data.rotate(-diff);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
// START METAMAPS CODE - initialize newTopic.metacode
|
||||||
|
var first = $(this.container).find('img').get(0)
|
||||||
|
Metamaps.Create.newTopic.metacode = $(first).data('id')
|
||||||
|
// END METAMAPS CODE
|
||||||
|
|
||||||
// If we have moved out of a carousel item (or the container itself),
|
// If we have moved out of a carousel item (or the container itself),
|
||||||
// restore the text of the front item in 1 second.
|
// restore the text of the front item in 1 second.
|
||||||
$(container).bind('mouseout',this,function(event){
|
$(container).bind('mouseout',this,function(event){
|
||||||
|
@ -247,11 +255,6 @@ jQuery.browser = browser;
|
||||||
this.showFrontText = function()
|
this.showFrontText = function()
|
||||||
{
|
{
|
||||||
if ( items[this.frontIndex] === undefined ) { return; } // Images might not have loaded yet.
|
if ( items[this.frontIndex] === undefined ) { return; } // Images might not have loaded yet.
|
||||||
// METAMAPS CODE
|
|
||||||
Metamaps.Create.newTopic.metacode = $(items[this.frontIndex].image).attr('data-id');
|
|
||||||
//$('img.cloudcarousel').css({"background":"none", "width":"","height":""});
|
|
||||||
//$(items[this.frontIndex].image).css({"width":"45px","height":"45px"});
|
|
||||||
// NOT METAMAPS CODE
|
|
||||||
$(options.titleBox).html( $(items[this.frontIndex].image).attr('title'));
|
$(options.titleBox).html( $(items[this.frontIndex].image).attr('title'));
|
||||||
$(options.altBox).html( $(items[this.frontIndex].image).attr('alt'));
|
$(options.altBox).html( $(items[this.frontIndex].image).attr('alt'));
|
||||||
};
|
};
|
||||||
|
|
File diff suppressed because it is too large
Load diff
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
@ -1,23 +0,0 @@
|
||||||
function SocketIoConnection(config) {
|
|
||||||
this.connection = io.connect(config.url, config.socketio);
|
|
||||||
}
|
|
||||||
|
|
||||||
SocketIoConnection.prototype.on = function (ev, fn) {
|
|
||||||
this.connection.on(ev, fn);
|
|
||||||
};
|
|
||||||
|
|
||||||
SocketIoConnection.prototype.emit = function () {
|
|
||||||
this.connection.emit.apply(this.connection, arguments);
|
|
||||||
};
|
|
||||||
|
|
||||||
SocketIoConnection.prototype.removeAllListeners = function () {
|
|
||||||
this.connection.removeAllListeners();
|
|
||||||
};
|
|
||||||
|
|
||||||
SocketIoConnection.prototype.getSessionid = function () {
|
|
||||||
return this.connection.socket.sessionid;
|
|
||||||
};
|
|
||||||
|
|
||||||
SocketIoConnection.prototype.disconnect = function () {
|
|
||||||
return this.connection.disconnect();
|
|
||||||
};
|
|
|
@ -1,41 +0,0 @@
|
||||||
var USERVOICE;
|
|
||||||
if(USERVOICE == undefined) {
|
|
||||||
USERVOICE = {};
|
|
||||||
}
|
|
||||||
|
|
||||||
USERVOICE.load = function (name, id, email, sso_token) {
|
|
||||||
// Include the UserVoice JavaScript SDK (only needed once on a page)
|
|
||||||
UserVoice=window.UserVoice||[];(function(){var uv=document.createElement('script');uv.type='text/javascript';uv.async=true;uv.src='//widget.uservoice.com/wybK0nSMNuhlWkIKzTyWg.js';var s=document.getElementsByTagName('script')[0];s.parentNode.insertBefore(uv,s)})();
|
|
||||||
|
|
||||||
//
|
|
||||||
// UserVoice Javascript SDK developer documentation:
|
|
||||||
// https://www.uservoice.com/o/javascript-sdk
|
|
||||||
//
|
|
||||||
|
|
||||||
// Set colors
|
|
||||||
UserVoice.push(['set', {
|
|
||||||
accent_color: '#448dd6',
|
|
||||||
trigger_color: 'white',
|
|
||||||
trigger_background_color: 'rgba(46, 49, 51, 0.6)'
|
|
||||||
}]);
|
|
||||||
|
|
||||||
// Identify the user and pass traits
|
|
||||||
// To enable, replace sample data with actual user traits and uncomment the line
|
|
||||||
if (name) {
|
|
||||||
UserVoice.push(['setSSO', sso_token]);
|
|
||||||
UserVoice.push(['identify', {
|
|
||||||
'email': email, // User’s email address
|
|
||||||
'name': name, // User’s real name
|
|
||||||
'id': id, // Optional: Unique id of the user
|
|
||||||
}]);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Add default trigger to the bottom-left corner of the window:
|
|
||||||
UserVoice.push(['addTrigger', { mode: 'contact', trigger_position: 'bottom-left' }]);
|
|
||||||
|
|
||||||
// Or, use your own custom trigger:
|
|
||||||
//UserVoice.push(['addTrigger', '#barometer_tab', { mode: 'contact' }]);
|
|
||||||
|
|
||||||
// Autoprompt for Satisfaction and SmartVote (only displayed under certain conditions)
|
|
||||||
UserVoice.push(['autoprompt', {}]);
|
|
||||||
};
|
|
3836
app/assets/javascripts/metamaps.secret.bundle.js
Normal file
3836
app/assets/javascripts/metamaps.secret.bundle.js
Normal file
File diff suppressed because one or more lines are too long
|
@ -1,24 +0,0 @@
|
||||||
/* global Metamaps */
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Metamaps.Erb.js.erb
|
|
||||||
*/
|
|
||||||
|
|
||||||
/* erb variables from rails */
|
|
||||||
window.Metamaps = window.Metamaps || {}
|
|
||||||
Metamaps.Erb = {}
|
|
||||||
Metamaps.Erb['REALTIME_SERVER'] = '<%= ENV['REALTIME_SERVER'] %>'
|
|
||||||
Metamaps.Erb['RAILS_ENV'] = '<%= ENV['RAILS_ENV'] %>'
|
|
||||||
Metamaps.Erb['junto_spinner_darkgrey.gif'] = '<%= asset_path('junto_spinner_darkgrey.gif') %>'
|
|
||||||
Metamaps.Erb['user.png'] = '<%= asset_path('user.png') %>'
|
|
||||||
Metamaps.Erb['icons/wildcard.png'] = '<%= asset_path('icons/wildcard.png') %>'
|
|
||||||
Metamaps.Erb['topic_description_signifier.png'] = '<%= asset_path('topic_description_signifier.png') %>'
|
|
||||||
Metamaps.Erb['topic_link_signifier.png'] = '<%= asset_path('topic_link_signifier.png') %>'
|
|
||||||
Metamaps.Erb['synapse16.png'] = '<%= asset_path('synapse16.png') %>'
|
|
||||||
Metamaps.Erb['import-example.png'] = '<%= asset_path('import-example.png') %>'
|
|
||||||
Metamaps.Erb['sounds/MM_sounds.mp3'] = '<%= asset_path 'sounds/MM_sounds.mp3' %>'
|
|
||||||
Metamaps.Erb['sounds/MM_sounds.ogg'] = '<%= asset_path 'sounds/MM_sounds.ogg' %>'
|
|
||||||
Metamaps.Metacodes = <%= Metacode.all.to_json.gsub(%r[(icon.*?)(\"},)], '\1?purple=stupid\2').html_safe %>
|
|
||||||
Metamaps.VERSION = '<%= METAMAPS_VERSION %>'
|
|
||||||
Metamaps.BUILD = '<%= METAMAPS_BUILD %>'
|
|
||||||
Metamaps.LAST_UPDATED = '<%= METAMAPS_LAST_UPDATED %>'
|
|
|
@ -1,15 +0,0 @@
|
||||||
// TODO document this user agent function
|
|
||||||
var labelType, useGradients, nativeTextSupport, animate
|
|
||||||
;(function () {
|
|
||||||
var ua = navigator.userAgent,
|
|
||||||
iStuff = ua.match(/iPhone/i) || ua.match(/iPad/i),
|
|
||||||
typeOfCanvas = typeof HTMLCanvasElement,
|
|
||||||
nativeCanvasSupport = (typeOfCanvas == 'object' || typeOfCanvas == 'function'),
|
|
||||||
textSupport = nativeCanvasSupport && (typeof document.createElement('canvas').getContext('2d').fillText == 'function')
|
|
||||||
// I'm setting this based on the fact that ExCanvas provides text support for IE
|
|
||||||
// and that as of today iPhone/iPad current text support is lame
|
|
||||||
labelType = (!nativeCanvasSupport || (textSupport && !iStuff)) ? 'Native' : 'HTML'
|
|
||||||
nativeTextSupport = labelType == 'Native'
|
|
||||||
useGradients = nativeCanvasSupport
|
|
||||||
animate = !(iStuff || !nativeCanvasSupport)
|
|
||||||
})()
|
|
12
app/assets/secret_stylesheets/application-secret.scss.erb
Normal file
12
app/assets/secret_stylesheets/application-secret.scss.erb
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
/*
|
||||||
|
* This is a manifest file that'll be compiled into application.css, which will include all the files
|
||||||
|
* listed below.
|
||||||
|
*
|
||||||
|
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
|
||||||
|
* or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
|
||||||
|
*
|
||||||
|
* You're free to add application-wide styles to this file and they'll appear at the top of the
|
||||||
|
* compiled file, but it's generally better to create a new file per style scope.
|
||||||
|
*
|
||||||
|
*= require ./special
|
||||||
|
*/
|
109
app/assets/secret_stylesheets/special.scss.erb
Normal file
109
app/assets/secret_stylesheets/special.scss.erb
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
#metacodeSelector {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.metacodeSelect {
|
||||||
|
border-top: 1px solid #DDD;
|
||||||
|
padding: 0;
|
||||||
|
background: #FFF;
|
||||||
|
|
||||||
|
.metacodeFilterInput {
|
||||||
|
width: 100px;
|
||||||
|
outline: none;
|
||||||
|
border: 0;
|
||||||
|
padding: 8px;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 14px;
|
||||||
|
color: #424242;
|
||||||
|
font-family: 'din-medium', helvetica, sans-serif;
|
||||||
|
}
|
||||||
|
|
||||||
|
.metacodeList {
|
||||||
|
list-style: none;
|
||||||
|
background: #FFF;
|
||||||
|
|
||||||
|
li {
|
||||||
|
padding: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&:hover, &.keySelect {
|
||||||
|
background: #4CAF50;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
padding-right: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.selectedMetacode {
|
||||||
|
float: left;
|
||||||
|
background: #FFF;
|
||||||
|
border-top-left-radius: 2px;
|
||||||
|
border-bottom-left-radius: 2px;
|
||||||
|
padding: 5px 10px 5px 6px;
|
||||||
|
vertical-align: top;
|
||||||
|
border-right: 1px solid #DDD;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
.selectedMetacode:hover, .selectedMetacode.isBeingSelected {
|
||||||
|
background: #EDEDED;
|
||||||
|
}
|
||||||
|
.selectedMetacode img {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.selectedMetacode span {
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
.selectedMetacode .downArrow {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: 0;
|
||||||
|
height: 0;
|
||||||
|
border-style: solid;
|
||||||
|
border-width: 8px 6px 0 6px;
|
||||||
|
border-color: #777 transparent transparent transparent;
|
||||||
|
margin-left: 2px;
|
||||||
|
margin-top: 4px;
|
||||||
|
}
|
||||||
|
.new_topic {
|
||||||
|
margin: 0;
|
||||||
|
margin-top: -17px;
|
||||||
|
white-space: nowrap;
|
||||||
|
}
|
||||||
|
#new_topic .twitter-typeahead {
|
||||||
|
position: relative !important;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
}
|
||||||
|
.new_topic #topic_name,
|
||||||
|
.new_topic .tt-hint {
|
||||||
|
border-radius: none;
|
||||||
|
border-top-right-radius: 2px;
|
||||||
|
border-bottom-right-radius: 2px;
|
||||||
|
}
|
||||||
|
.openMetacodeSwitcher {
|
||||||
|
top: -16px;
|
||||||
|
left: -16px;
|
||||||
|
}
|
||||||
|
#metacodeImg {
|
||||||
|
height: 120px;
|
||||||
|
width: 380px;
|
||||||
|
display: none;
|
||||||
|
position: absolute !important;
|
||||||
|
top: -30px;
|
||||||
|
z-index: -1;
|
||||||
|
}
|
||||||
|
#metacodeImgTitle {
|
||||||
|
display: none;
|
||||||
|
float: left;
|
||||||
|
width: 120px;
|
||||||
|
text-align: center;
|
||||||
|
margin-left: 110px;
|
||||||
|
}
|
|
@ -56,16 +56,15 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
li.toggledOff {
|
li.toggledOff {
|
||||||
opacity: 0.4;
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.blackBox {
|
.centerContent {
|
||||||
width: 760px;
|
width: 760px;
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
padding: 80px 0 60px 20px;
|
padding: 80px 0 60px 20px;
|
||||||
background: rgba(0, 0, 0, 0.4);
|
background: rgba(125, 125, 125, 0.4);
|
||||||
color: white;
|
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
|
||||||
|
@ -85,10 +84,10 @@
|
||||||
display: table-row;
|
display: table-row;
|
||||||
}
|
}
|
||||||
tr:nth-child(odd) {
|
tr:nth-child(odd) {
|
||||||
background: rgba(0, 0, 0, 0.2);
|
background: rgba(125, 125, 125, 0.2);
|
||||||
}
|
}
|
||||||
tr:nth-child(even) {
|
tr:nth-child(even) {
|
||||||
background: rgba(0, 0, 0, 0.3);
|
background: rgba(125, 125, 125, 0.3);
|
||||||
}
|
}
|
||||||
th,
|
th,
|
||||||
td {
|
td {
|
||||||
|
|
|
@ -78,11 +78,18 @@ html {
|
||||||
|
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
background: #d8d9da url(<%= asset_data_uri('shattered_@2X.png') %>);
|
background: #d8d9da url(<%= asset_path('shattered_@2X.png') %>);
|
||||||
font-family: 'din-medium', helvetica, sans-serif;
|
font-family: 'din-medium', helvetica, sans-serif;
|
||||||
color: #424242;
|
color: #424242;
|
||||||
-moz-osx-font-smoothing: grayscale;
|
-moz-osx-font-smoothing: grayscale;
|
||||||
overflow-x: hidden;
|
overflow-x: hidden;
|
||||||
|
|
||||||
|
&.controller-main,
|
||||||
|
&.controller-maps,
|
||||||
|
&.controller-topics,
|
||||||
|
&.controller-explore {
|
||||||
|
overflow-y: hidden;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
h1,
|
h1,
|
||||||
h2,
|
h2,
|
||||||
|
@ -186,10 +193,6 @@ button.button.btn-no:hover {
|
||||||
display: block;
|
display: block;
|
||||||
width: 830px;
|
width: 830px;
|
||||||
}
|
}
|
||||||
.requestInvite {
|
|
||||||
display: block;
|
|
||||||
margin: -720px auto 0;
|
|
||||||
}
|
|
||||||
.new_session,
|
.new_session,
|
||||||
.new_user,
|
.new_user,
|
||||||
.edit_user,
|
.edit_user,
|
||||||
|
@ -524,10 +527,12 @@ button.button.btn-no:hover {
|
||||||
left: -1000px;
|
left: -1000px;
|
||||||
display: block;
|
display: block;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 340px;
|
|
||||||
margin: -40px 0 0 -35px;
|
margin: -40px 0 0 -35px;
|
||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
body:not(.action-conversation) .new_topic {
|
||||||
|
width: 340px;
|
||||||
|
}
|
||||||
|
|
||||||
#new_topic .twitter-typeahead {
|
#new_topic .twitter-typeahead {
|
||||||
position: absolute !important;
|
position: absolute !important;
|
||||||
|
@ -663,9 +668,21 @@ label {
|
||||||
position: relative;
|
position: relative;
|
||||||
/*overflow:hidden; */
|
/*overflow:hidden; */
|
||||||
}
|
}
|
||||||
.main.compressed {
|
.compressed {
|
||||||
width: calc(100% - 300px);
|
.upperRightUI {
|
||||||
|
right: 324px;
|
||||||
|
}
|
||||||
|
.upperRightMapButtons {
|
||||||
|
right: 434px;
|
||||||
|
}
|
||||||
|
.mapControls {
|
||||||
|
right: 324px;
|
||||||
|
}
|
||||||
|
.infoAndHelp {
|
||||||
|
right: 370px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#infovis-canvas {
|
#infovis-canvas {
|
||||||
-webkit-touch-callout: none;
|
-webkit-touch-callout: none;
|
||||||
-webkit-user-select: none;
|
-webkit-user-select: none;
|
||||||
|
@ -766,9 +783,9 @@ label {
|
||||||
}
|
}
|
||||||
.sidebarAccountIcon img {
|
.sidebarAccountIcon img {
|
||||||
border-radius: 16px;
|
border-radius: 16px;
|
||||||
|
width: 32px;
|
||||||
}
|
}
|
||||||
.sidebarAccountBox {
|
.sidebarAccountBox {
|
||||||
display: none;
|
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
.authenticated .sidebarAccountBox {
|
.authenticated .sidebarAccountBox {
|
||||||
|
@ -809,6 +826,7 @@ label {
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
line-height: 14px;
|
line-height: 14px;
|
||||||
color: #757575;
|
color: #757575;
|
||||||
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
.accountListItem:hover {
|
.accountListItem:hover {
|
||||||
color: #424242;
|
color: #424242;
|
||||||
|
@ -819,7 +837,7 @@ label {
|
||||||
position:absolute;
|
position:absolute;
|
||||||
pointer-events:none;
|
pointer-events:none;
|
||||||
background-repeat:no-repeat;
|
background-repeat:no-repeat;
|
||||||
background-image: url(<%= asset_data_uri('user_sprite.png') %>);
|
background-image: url(<%= asset_path('user_sprite.png') %>);
|
||||||
}
|
}
|
||||||
.accountSettings .accountIcon {
|
.accountSettings .accountIcon {
|
||||||
background-position: 0 0;
|
background-position: 0 0;
|
||||||
|
@ -827,6 +845,9 @@ label {
|
||||||
.accountAdmin .accountIcon {
|
.accountAdmin .accountIcon {
|
||||||
background-position: 0 -32px;
|
background-position: 0 -32px;
|
||||||
}
|
}
|
||||||
|
.accountApps .accountIcon {
|
||||||
|
background-position: 0 -32px;
|
||||||
|
}
|
||||||
.accountInvite .accountIcon {
|
.accountInvite .accountIcon {
|
||||||
background-position: 0 -64px;
|
background-position: 0 -64px;
|
||||||
}
|
}
|
||||||
|
@ -1027,7 +1048,6 @@ label[for="user_remember_me"] {
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebarFilterBox {
|
.sidebarFilterBox {
|
||||||
display:none;
|
|
||||||
width: 319px;
|
width: 319px;
|
||||||
padding: 16px 0;
|
padding: 16px 0;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
@ -1238,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);
|
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-permission:hover > ul,
|
||||||
.rightclickmenu .rc-metacode:hover > ul,
|
.rightclickmenu .rc-metacode:hover #metacodeOptions > ul,
|
||||||
.rightclickmenu .rc-siblings:hover > ul {
|
.rightclickmenu .rc-siblings:hover > ul {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
@ -1267,7 +1287,7 @@ h3.filterBox {
|
||||||
.rightclickmenu li.toPrivate .rc-perm-icon {
|
.rightclickmenu li.toPrivate .rc-perm-icon {
|
||||||
background-position: -24px 0;
|
background-position: -24px 0;
|
||||||
}
|
}
|
||||||
.rightclickmenu .rc-metacode > ul > li,
|
.rightclickmenu .rc-metacode #metacodeOptions > ul > li,
|
||||||
.rightclickmenu .rc-siblings > ul > li {
|
.rightclickmenu .rc-siblings > ul > li {
|
||||||
padding: 6px 24px 6px 8px;
|
padding: 6px 24px 6px 8px;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
|
@ -1548,6 +1568,7 @@ h3.filterBox {
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
margin: 0.75em;
|
margin: 0.75em;
|
||||||
padding: 0.75em;
|
padding: 0.75em;
|
||||||
|
padding-top: 0.85em;
|
||||||
height: 3em;
|
height: 3em;
|
||||||
background-color: #AAB0FB;
|
background-color: #AAB0FB;
|
||||||
border-radius: 0.3em;
|
border-radius: 0.3em;
|
||||||
|
@ -1894,14 +1915,10 @@ input.collaboratorSearchField {
|
||||||
background-position: -32px 0;
|
background-position: -32px 0;
|
||||||
}
|
}
|
||||||
.yourMap .mapPermission:hover {
|
.yourMap .mapPermission:hover {
|
||||||
background-image: url(<%= asset_data_uri('arrowperms_sprite.png') %>);
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-position: -32px 0;
|
|
||||||
}
|
}
|
||||||
.yourMap .mapPermission.minimize {
|
.yourMap .mapPermission.minimize {
|
||||||
background-image: url(<%= asset_data_uri('arrowperms_sprite.png') %>) !important;
|
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
background-position: 0 0;
|
|
||||||
}
|
}
|
||||||
.mapInfoBox .mapPermission .permissionSelect {
|
.mapInfoBox .mapPermission .permissionSelect {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
@ -2002,6 +2019,7 @@ input.collaboratorSearchField {
|
||||||
position: relative;
|
position: relative;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
display: none;
|
display: none;
|
||||||
|
padding: 0 2px;
|
||||||
}
|
}
|
||||||
.mapInfoShareIcon {
|
.mapInfoShareIcon {
|
||||||
width: 24px;
|
width: 24px;
|
||||||
|
@ -2041,6 +2059,43 @@ and it won't be important on password protected instances */
|
||||||
.yourMap .mapInfoDelete {
|
.yourMap .mapInfoDelete {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mapInfoButtonsWrapper .mapInfoThumbnail {
|
||||||
|
display: block;
|
||||||
|
background-image: url(<%= asset_path('screenshot_sprite.png') %>);
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
|
||||||
|
& > span {
|
||||||
|
bottom: -8px;
|
||||||
|
right: 2px;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #e0e0e0;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
color: white;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.tooltip {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-position: -32px 0;
|
||||||
|
|
||||||
|
.tooltip {
|
||||||
|
display: block;
|
||||||
|
position: absolute;
|
||||||
|
bottom: 30px;
|
||||||
|
background: black;
|
||||||
|
color: white;
|
||||||
|
border-radius: 2px;
|
||||||
|
padding: 3px 5px 2px 5px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
.mapInfoButtonsWrapper span {
|
.mapInfoButtonsWrapper span {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
|
@ -2105,7 +2160,6 @@ and it won't be important on password protected instances */
|
||||||
}
|
}
|
||||||
#lightbox_content {
|
#lightbox_content {
|
||||||
width: 800px;
|
width: 800px;
|
||||||
height: 500px;
|
|
||||||
max-height: 90vh;
|
max-height: 90vh;
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
@ -2190,41 +2244,34 @@ and it won't be important on password protected instances */
|
||||||
color: #00bcd4;
|
color: #00bcd4;
|
||||||
}
|
}
|
||||||
.lightbox_links .lightboxAboutIcon {
|
.lightbox_links .lightboxAboutIcon {
|
||||||
background-image: url(<%= asset_data_uri('about_sprite.png') %>);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
width:32px;
|
width:32px;
|
||||||
height:32px;
|
height:32px;
|
||||||
margin:10px auto;
|
margin:10px auto;
|
||||||
}
|
}
|
||||||
#lightbox_metamapps .lightboxAboutIcon {
|
.icon_twitter .lightboxAboutIcon,
|
||||||
|
.icon_source_code .lightboxAboutIcon,
|
||||||
|
.icon_terms .lightboxAboutIcon {
|
||||||
|
background-image: url(<%= asset_data_uri('about_sprite.png') %>);
|
||||||
|
background-repeat: no-repeat;
|
||||||
background-position: 0 0;
|
background-position: 0 0;
|
||||||
}
|
}
|
||||||
#lightbox_community .lightboxAboutIcon {
|
.icon_twitter .lightboxAboutIcon {
|
||||||
background-position: -32px 0;
|
background-position: 0 0;
|
||||||
}
|
&:hover {
|
||||||
#lightbox_source .lightboxAboutIcon {
|
|
||||||
background-position: -64px 0;
|
|
||||||
}
|
|
||||||
#lightbox_blog .lightboxAboutIcon {
|
|
||||||
background-position: -96px 0;
|
|
||||||
}
|
|
||||||
#lightbox_term .lightboxAboutIcon {
|
|
||||||
background-position: -128px 0;
|
|
||||||
}
|
|
||||||
#lightbox_metamapps:hover .lightboxAboutIcon {
|
|
||||||
background-position: 0 -32px;
|
background-position: 0 -32px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#lightbox_community:hover .lightboxAboutIcon {
|
.icon_source_code .lightboxAboutIcon {
|
||||||
background-position: -32px -32px;
|
background-position: -64px 0;
|
||||||
}
|
&:hover {
|
||||||
#lightbox_source:hover .lightboxAboutIcon {
|
|
||||||
background-position: -64px -32px;
|
background-position: -64px -32px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#lightbox_blog:hover .lightboxAboutIcon {
|
.icon_terms .lightboxAboutIcon {
|
||||||
background-position: -96px -32px;
|
background-position: -128px 0;
|
||||||
}
|
&:hover {
|
||||||
#lightbox_term:hover .lightboxAboutIcon {
|
|
||||||
background-position: -128px -32px;
|
background-position: -128px -32px;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* jquery ui tabs */
|
/* jquery ui tabs */
|
||||||
|
@ -2268,6 +2315,9 @@ and it won't be important on password protected instances */
|
||||||
}
|
}
|
||||||
/* switch metacode set */
|
/* switch metacode set */
|
||||||
|
|
||||||
|
#switchMetacodes > p {
|
||||||
|
margin: 16px 0 16px 0;
|
||||||
|
}
|
||||||
#metacodeSwitchTabs {
|
#metacodeSwitchTabs {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
font-size: 17px;
|
font-size: 17px;
|
||||||
|
@ -2275,28 +2325,43 @@ and it won't be important on password protected instances */
|
||||||
border: none;
|
border: none;
|
||||||
background: none;
|
background: none;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
|
||||||
#metacodeSwitchTabs .setDesc {
|
.setDesc,
|
||||||
margin-bottom: 5px;
|
.selectAll,
|
||||||
font-family: 'din-medium', helvetica, sans-serif;
|
.selectNone {
|
||||||
color: #424242;
|
margin-bottom: 5px;
|
||||||
font-size: 14px;
|
font-family: 'din-medium', helvetica, sans-serif;
|
||||||
text-align: justify;
|
color: #424242;
|
||||||
padding-right: 16px;
|
font-size: 14px;
|
||||||
}
|
text-align: justify;
|
||||||
#switchMetacodes > p {
|
padding-right: 16px;
|
||||||
margin: 16px 0 16px 0;
|
display: inline-block;
|
||||||
}
|
}
|
||||||
#metacodeSwitchTabs > ul {
|
|
||||||
width: 130px;
|
.selectAll,
|
||||||
}
|
.selectNone {
|
||||||
#metacodeSwitchTabs > ul li {
|
float: right;
|
||||||
font-size: 14px;
|
cursor: pointer;
|
||||||
text-transform: uppercase;
|
|
||||||
}
|
&:hover,
|
||||||
#metacodeSwitchTabs li.ui-state-active a {
|
&.selected {
|
||||||
color: #00BCD4;
|
color: #00bcd4;
|
||||||
cursor: pointer;
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > ul {
|
||||||
|
width: 130px;
|
||||||
|
|
||||||
|
li {
|
||||||
|
font-size: 14px;
|
||||||
|
text-transform: uppercase;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
li.ui-state-active a {
|
||||||
|
color: #00BCD4;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.metacodeSwitchTab {
|
.metacodeSwitchTab {
|
||||||
max-height: 300px;
|
max-height: 300px;
|
||||||
|
@ -2865,146 +2930,18 @@ and it won't be important on password protected instances */
|
||||||
color: #424242;
|
color: #424242;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Admin Pages */
|
|
||||||
|
|
||||||
.blackBox {
|
|
||||||
width: 760px;
|
|
||||||
margin: 0 auto;
|
|
||||||
padding: 20px 0 60px 20px;
|
|
||||||
background: rgba(0, 0, 0, 0.4);
|
|
||||||
color: white;
|
|
||||||
overflow: hidden;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.blackBox .metacodeSetsDescription {
|
|
||||||
width: 314px;
|
|
||||||
}
|
|
||||||
.blackBox td.metacodeSetDesc {
|
|
||||||
width: 314px;
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
.blackBox .metacodeSetImage {
|
|
||||||
width: 36px;
|
|
||||||
height: 36px;
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
.blackBox tr {
|
|
||||||
display: table-row;
|
|
||||||
}
|
|
||||||
.blackBox tr:nth-child(odd) {
|
|
||||||
background: rgba(0, 0, 0, 0.2);
|
|
||||||
}
|
|
||||||
.blackBox tr:nth-child(even) {
|
|
||||||
background: rgba(0, 0, 0, 0.3);
|
|
||||||
}
|
|
||||||
.blackBox th,
|
|
||||||
.blackBox td {
|
|
||||||
padding: 10px;
|
|
||||||
}
|
|
||||||
.blackBox td.iconURL {
|
|
||||||
max-width: 415px;
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
.blackBox td.iconColor {
|
|
||||||
|
|
||||||
}
|
|
||||||
.blackBox .field {
|
|
||||||
margin: 15px 0 5px;
|
|
||||||
}
|
|
||||||
.blackBox label {
|
|
||||||
float: left;
|
|
||||||
width: 100px;
|
|
||||||
margin-right: 15px;
|
|
||||||
}
|
|
||||||
.blackBox input[type="text"] {
|
|
||||||
width: 336px;
|
|
||||||
height: 32px;
|
|
||||||
font-size: 15px;
|
|
||||||
direction: ltr;
|
|
||||||
-webkit-appearance: none;
|
|
||||||
appearance: none;
|
|
||||||
display: inline-block;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0 8px;
|
|
||||||
background: #fff;
|
|
||||||
border: 1px solid #d9d9d9;
|
|
||||||
border-top: 1px solid #c0c0c0;
|
|
||||||
-webkit-box-sizing: border-box;
|
|
||||||
-moz-box-sizing: border-box;
|
|
||||||
box-sizing: border-box;
|
|
||||||
-webkit-border-radius: 1px;
|
|
||||||
-moz-border-radius: 1px;
|
|
||||||
border-radius: 1px;
|
|
||||||
font: -webkit-small-control;
|
|
||||||
color: initial;
|
|
||||||
letter-spacing: normal;
|
|
||||||
word-spacing: normal;
|
|
||||||
text-transform: none;
|
|
||||||
text-indent: 0px;
|
|
||||||
text-shadow: none;
|
|
||||||
display: inline-block;
|
|
||||||
text-align: start;
|
|
||||||
font-family: arial;
|
|
||||||
}
|
|
||||||
.blackBox input[type="text"]:hover,
|
|
||||||
.blackBox textarea:hover {
|
|
||||||
border: 1px solid #b9b9b9;
|
|
||||||
border-top: 1px solid #a0a0a0;
|
|
||||||
-webkit-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
|
||||||
-moz-box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
|
||||||
box-shadow: inset 0 1px 2px rgba(0, 0, 0, 0.1);
|
|
||||||
}
|
|
||||||
.blackBox textarea {
|
|
||||||
padding: 8px;
|
|
||||||
border: 1px solid #d9d9d9;
|
|
||||||
border-top: 1px solid #c0c0c0;
|
|
||||||
resize: none;
|
|
||||||
font: -webkit-small-control;
|
|
||||||
letter-spacing: normal;
|
|
||||||
word-spacing: normal;
|
|
||||||
text-transform: none;
|
|
||||||
text-indent: 0px;
|
|
||||||
text-shadow: none;
|
|
||||||
text-align: start;
|
|
||||||
font-family: arial;
|
|
||||||
font-size: 15px;
|
|
||||||
line-height: 17px;
|
|
||||||
width: 318px;
|
|
||||||
}
|
|
||||||
.blackBox .allMetacodes {
|
|
||||||
padding: 5px 0;
|
|
||||||
}
|
|
||||||
.blackBox a.button {
|
|
||||||
margin-right: 20px;
|
|
||||||
line-height: 40px;
|
|
||||||
}
|
|
||||||
.blackBox a.button,
|
|
||||||
.blackBox input.add {
|
|
||||||
float: left;
|
|
||||||
margin-top: 5px;
|
|
||||||
height: 40px;
|
|
||||||
font-size: 17px;
|
|
||||||
width: auto;
|
|
||||||
padding: 0 30px;
|
|
||||||
cursor: pointer;
|
|
||||||
font-weight: normal;
|
|
||||||
}
|
|
||||||
.blackBox a.button:hover,
|
|
||||||
.blackBox input.add:hover {
|
|
||||||
-webkit-box-shadow: none;
|
|
||||||
box-shadow: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* request */
|
/* request */
|
||||||
|
|
||||||
#wrapper .requestInvite {
|
.requestInvite {
|
||||||
width: 700px;
|
width: 700px;
|
||||||
margin: 0 auto;
|
|
||||||
padding: 0 0 60px 0;
|
|
||||||
background: #FFFFFF;
|
background: #FFFFFF;
|
||||||
color: white;
|
color: white;
|
||||||
height: 100%;
|
height: calc(100% - 52px);
|
||||||
overflow: hidden;
|
z-index: 1;
|
||||||
|
position: relative;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -350px;
|
||||||
|
margin-top: 52px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.home_bg {
|
.home_bg {
|
||||||
|
@ -3074,3 +3011,21 @@ script.data-gratipay-username {
|
||||||
display: inline;
|
display: inline;
|
||||||
float: left;
|
float: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
}
|
||||||
|
|
|
@ -1,17 +1,14 @@
|
||||||
.centerContent {
|
.centerContent {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 92px auto 0 auto;
|
margin: 0 auto;
|
||||||
padding: 20px 0 60px 20px;
|
width: auto;
|
||||||
width: 760px;
|
max-width: 800px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
box-shadow: 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24);
|
box-shadow: 0 1px 3px rgba(0,0,0,.12),0 1px 2px rgba(0,0,0,.24);
|
||||||
background: #fff;
|
background: #fff;
|
||||||
-webkit-border-radius: 3px;
|
box-sizing: border-box;
|
||||||
-moz-border-radius: 3px;
|
|
||||||
border-radius: 3px;
|
|
||||||
border: 1px solid #dcdcdc;
|
|
||||||
margin-bottom: 10px;
|
|
||||||
padding: 15px;
|
padding: 15px;
|
||||||
|
font-family: 'din-regular', sans-serif;
|
||||||
}
|
}
|
||||||
|
|
||||||
.centerContent .page-header {
|
.centerContent .page-header {
|
||||||
|
@ -129,3 +126,9 @@
|
||||||
box-sizing: border-box;
|
box-sizing: border-box;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.centerContent.withPadding {
|
||||||
|
margin-top: 1em;
|
||||||
|
margin-bottom: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,11 +1,19 @@
|
||||||
|
$mid-gray: #8A8A8A;
|
||||||
|
$mid-gray-opacity: rgba(66, 66, 66, 0.6);
|
||||||
|
|
||||||
.nameCounter {
|
.nameCounter {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 1px;
|
bottom: 1px;
|
||||||
right: 2px;
|
right: 2px;
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
font-family: helvetica;
|
font-family: helvetica, sans-serif;
|
||||||
color: #727272;
|
color: #727272;
|
||||||
line-height: 11px;
|
line-height: 11px;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.riek-editing + .nameCounter {
|
||||||
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.nameCounter.forMap {
|
.nameCounter.forMap {
|
||||||
|
@ -17,7 +25,6 @@
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#center-container {
|
#center-container {
|
||||||
position:relative;
|
position:relative;
|
||||||
height:100%;
|
height:100%;
|
||||||
|
@ -29,7 +36,6 @@
|
||||||
|
|
||||||
.showcard {
|
.showcard {
|
||||||
position:absolute;
|
position:absolute;
|
||||||
display:none;
|
|
||||||
top:100px;
|
top:100px;
|
||||||
left:100px;
|
left:100px;
|
||||||
width:300px;
|
width:300px;
|
||||||
|
@ -39,7 +45,7 @@
|
||||||
z-index:2;
|
z-index:2;
|
||||||
color: #424242;
|
color: #424242;
|
||||||
border-radius:2px;
|
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 {
|
.text {
|
||||||
|
@ -50,7 +56,6 @@
|
||||||
width:100%;
|
width:100%;
|
||||||
height:100%;
|
height:100%;
|
||||||
position: absolute;
|
position: absolute;
|
||||||
display: none;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.showcard .permission {
|
.showcard .permission {
|
||||||
|
@ -62,7 +67,6 @@
|
||||||
display:block;
|
display:block;
|
||||||
position:relative;
|
position:relative;
|
||||||
width:100%;
|
width:100%;
|
||||||
min-height:360px;
|
|
||||||
z-index: 25;
|
z-index: 25;
|
||||||
}
|
}
|
||||||
.CardOnGraph.hasAttachment {
|
.CardOnGraph.hasAttachment {
|
||||||
|
@ -70,11 +74,11 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .title {
|
.CardOnGraph .title {
|
||||||
font-size: 18px;
|
word-break: break-word;
|
||||||
line-height: 22px;
|
font-size: 20px;
|
||||||
|
line-height: 24px;
|
||||||
display: table;
|
display: table;
|
||||||
padding: 8px 0 16px;
|
padding: 20px 0;
|
||||||
height: 80px;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
font-family: 'din-regular', sans-serif;
|
font-family: 'din-regular', sans-serif;
|
||||||
width: 300px;
|
width: 300px;
|
||||||
|
@ -93,12 +97,11 @@
|
||||||
cursor: text;
|
cursor: text;
|
||||||
}
|
}
|
||||||
|
|
||||||
.showcard .best_in_place_name textarea, .showcard .best_in_place_name input {
|
.showcard .title .riek-editing {
|
||||||
font-family: 'din-regular', sans-serif;
|
font-family: 'din-regular', sans-serif;
|
||||||
color: #424242;
|
color: #424242;
|
||||||
font-size: 18px;
|
font-size: 20px;
|
||||||
line-height: 22px;
|
line-height: 24px;
|
||||||
height: 15px;
|
|
||||||
padding: 5px 0;
|
padding: 5px 0;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
@ -112,54 +115,76 @@
|
||||||
.CardOnGraph .scroll {
|
.CardOnGraph .scroll {
|
||||||
display:block;
|
display:block;
|
||||||
padding: 8px 0 8px 16px;
|
padding: 8px 0 8px 16px;
|
||||||
height: 152px;
|
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
line-height:15px;
|
line-height:15px;
|
||||||
font-family: helvetica, sans-serif;
|
font-family: helvetica, sans-serif;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|
||||||
|
p.emptyDesc {
|
||||||
|
color: $mid-gray-opacity;
|
||||||
|
}
|
||||||
|
|
||||||
|
a.mdSupport {
|
||||||
|
color: #4fb5c0;
|
||||||
|
font-size: 11px;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.riek-editing + .mdSupport {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
.CardOnGraph.hasAttachment .scroll {
|
.CardOnGraph.hasAttachment .scroll {
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .best_in_place_desc textarea {
|
.CardOnGraph .desc .riek-editing {
|
||||||
font-size: 13px;
|
font-size: 13px;
|
||||||
line-height:15px;
|
line-height:15px;
|
||||||
font-family: helvetica, sans-serif;
|
font-family: helvetica, sans-serif;
|
||||||
color: #424242;
|
color: #424242;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
width: 100%;
|
width: 258px;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
border: 0;
|
border: 0;
|
||||||
outline: none;
|
outline: none;
|
||||||
font-size: 12px;
|
|
||||||
line-height: 15px;
|
|
||||||
background: none;
|
background: none;
|
||||||
resize: none;
|
overflow-y: scroll;
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .desc h3 {
|
/*
|
||||||
font-style:normal;
|
* Styling for Markdown in topic cards
|
||||||
margin-top:5px;
|
*/
|
||||||
|
|
||||||
|
.CardOnGraph .desc {
|
||||||
|
p, ol, ul {
|
||||||
|
padding: 0.15em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
h1, h2, h3, h4, h5, h6 {
|
||||||
|
font-style: normal;
|
||||||
|
padding: 0.25em 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
ol,
|
||||||
|
ul {
|
||||||
|
margin-left: 1em;
|
||||||
|
}
|
||||||
|
|
||||||
|
a:hover {
|
||||||
|
text-decoration: underline;
|
||||||
|
opacity: 0.9;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .desc ol,
|
/*
|
||||||
.CardOnGraph .desc ul {
|
* End Markdown styling
|
||||||
margin-left: 1em;
|
*/
|
||||||
|
|
||||||
}
|
.CardOnGraph .riek_desc {
|
||||||
.CardOnGraph .desc a:hover {
|
|
||||||
text-decoration: underline;
|
|
||||||
opacity: 0.9;
|
|
||||||
}
|
|
||||||
|
|
||||||
.CardOnGraph .best_in_place_desc {
|
|
||||||
display:block;
|
display:block;
|
||||||
margin-top:2px;
|
padding-right: 26px;
|
||||||
padding-right: 18px;
|
|
||||||
margin-right: 8px;
|
|
||||||
}
|
}
|
||||||
.canEdit .CardOnGraph .best_in_place_desc:hover {
|
.canEdit .CardOnGraph .riek_desc:not(.riek-editing):hover {
|
||||||
background-image: url(<%= asset_data_uri('edit.png') %>);
|
background-image: url(<%= asset_data_uri('edit.png') %>);
|
||||||
background-position: top right;
|
background-position: top right;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
|
@ -171,155 +196,215 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .links {
|
.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;
|
position: relative;
|
||||||
color: #424242;
|
z-index: 2;
|
||||||
font-size: 14px;
|
|
||||||
line-height:14px;
|
.linkItem {
|
||||||
height:12px;
|
float: left;
|
||||||
padding:17px 0;
|
z-index: 1;
|
||||||
}
|
position: relative;
|
||||||
.linkItem a {
|
color: #424242;
|
||||||
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 {
|
.CardOnGraph .info {
|
||||||
position:absolute;
|
|
||||||
width:100%;
|
|
||||||
z-index:1;
|
|
||||||
padding: 0;
|
|
||||||
height: 48px;
|
|
||||||
}
|
|
||||||
.linkItem.contributor {
|
|
||||||
margin-left:40px;
|
|
||||||
z-index:1;
|
|
||||||
padding:17px 16px 17px 30px;
|
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
|
||||||
.contributor .contributorIcon {
|
|
||||||
position: absolute;
|
|
||||||
top: 8px;
|
|
||||||
left: 0;
|
|
||||||
border-radius: 16px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contributor:hover .contributorName {
|
.linkItem {
|
||||||
display: block;
|
float: left;
|
||||||
}
|
z-index: 1;
|
||||||
|
position: relative;
|
||||||
|
color: $mid-gray-opacity;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 14px;
|
||||||
|
|
||||||
.contributorName {
|
a {
|
||||||
display: none;
|
color: $mid-gray-opacity;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
.contributor div:before {
|
.contributor {
|
||||||
content: '';
|
bottom: 7px;
|
||||||
position: absolute;
|
margin-left: 16px;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
.linkItem.mapCount {
|
.contributorIcon {
|
||||||
margin-left: 12px;
|
position: relative;
|
||||||
width: 24px;
|
display: inline-block;
|
||||||
padding:17px 0 17px 36px;
|
vertical-align: middle;
|
||||||
}
|
border-radius: 16px;
|
||||||
.linkItem.mapCount .mapCountIcon {
|
margin: 5px 5px 5px 0;
|
||||||
position: absolute;
|
top: 11px;
|
||||||
top: 8px;
|
left: 0;
|
||||||
left: 0;
|
}
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
background-image: url(<%= asset_data_uri('map32_sprite.png') %>);
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: 0 0;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.linkItem.mapCount:hover .mapCountIcon {
|
|
||||||
background-position: 0 -32px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.linkItem.mapCount:hover .hoverTip {
|
span {
|
||||||
display: block;
|
font-family: 'din-regular', sans-serif;
|
||||||
}
|
font-size: 14px;
|
||||||
.CardOnGraph .mapCount .tip, .CardonGraph .mapCount .hoverTip {
|
}
|
||||||
top: 44px;
|
|
||||||
left: 0px;
|
|
||||||
font-size: 12px !important;
|
|
||||||
}
|
|
||||||
|
|
||||||
.hoverTip {
|
.contributorName {
|
||||||
white-space: nowrap;
|
font-family: din-regular;
|
||||||
font-family: 'din-regular';
|
margin-top: 20px;
|
||||||
top: 44px;
|
display: inline-block;
|
||||||
left: 0px;
|
vertical-align: middle;
|
||||||
font-size: 12px !important;
|
width: 97px;
|
||||||
display: none;
|
padding: 0 8px 0 4px;
|
||||||
position: absolute;
|
white-space: nowrap;
|
||||||
background: black;
|
overflow: hidden;
|
||||||
color: white;
|
text-overflow: ellipsis;
|
||||||
border-radius: 4px;
|
}
|
||||||
line-height: 17px;
|
}
|
||||||
padding: 3px 5px 2px;
|
|
||||||
z-index: 100;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
.mapCount {
|
||||||
|
padding:17px 38px 17px 0;
|
||||||
|
width: 22px;
|
||||||
|
text-align: right;
|
||||||
|
|
||||||
.CardOnGraph .mapCount .tip:before, .CardOnGraph .mapCount .hoverTip:before {
|
.mapCountIcon {
|
||||||
content: '';
|
position: absolute;
|
||||||
position: absolute;
|
top: 8px;
|
||||||
top: 26px;
|
right: 0;
|
||||||
left: 10px;
|
width: 32px;
|
||||||
margin-top: -30px;
|
height: 32px;
|
||||||
width: 0;
|
background-image: url(<%= asset_data_uri('map32_sprite.png') %>);
|
||||||
height: 0;
|
background-repeat: no-repeat;
|
||||||
border-bottom: 4px solid #000000;
|
background-position: 0 0;
|
||||||
border-left: 5px solid transparent;
|
cursor: pointer;
|
||||||
border-right: 5px solid transparent;
|
opacity: 0.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .mapCount .tip li {
|
&:hover .mapCountIcon {
|
||||||
list-style-type: none;
|
background-position: 0 -32px;
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
.CardOnGraph .mapCount li.hideExtra {
|
.tip, .hoverTip {
|
||||||
display: none;
|
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 {
|
.showMore {
|
||||||
|
@ -327,66 +412,10 @@
|
||||||
color: #4FC059;
|
color: #4FC059;
|
||||||
}
|
}
|
||||||
|
|
||||||
.mapCount .tip a {
|
.linkItem.mapPerm {
|
||||||
color: white;
|
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 {
|
.mapPerm {
|
||||||
width: 32px;
|
width: 32px;
|
||||||
height: 32px;
|
height: 32px;
|
||||||
|
@ -408,14 +437,10 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.yourTopic .mapPerm:hover, .yourEdge .mapPerm:hover {
|
.yourTopic .mapPerm:hover, .yourEdge .mapPerm:hover {
|
||||||
background-image: url(<%= asset_data_uri('arrowperms_sprite.png') %>);
|
|
||||||
background-position: -32px 0;
|
|
||||||
cursor:pointer;
|
cursor:pointer;
|
||||||
}
|
}
|
||||||
.yourTopic .mapPerm.minimize, .yourEdge .mapPerm.minimize {
|
.yourTopic .mapPerm.minimize, .yourEdge .mapPerm.minimize {
|
||||||
background-image: url(<%= asset_data_uri('arrowperms_sprite.png') %>) !important;
|
cursor: pointer;
|
||||||
background-position: 0 0;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
}
|
||||||
.mapPerm .permissionSelect {
|
.mapPerm .permissionSelect {
|
||||||
list-style: none;
|
list-style: none;
|
||||||
|
@ -451,60 +476,52 @@ cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .metacodeTitle {
|
.CardOnGraph .metacodeTitle {
|
||||||
font-style: italic;
|
font-family: 'din-regular';
|
||||||
font-family: 'vinyl';
|
|
||||||
text-transform: uppercase;
|
|
||||||
position: absolute;
|
|
||||||
line-height: 24px;
|
line-height: 24px;
|
||||||
height:24px;
|
height: 26px;
|
||||||
font-size: 24px;
|
font-size: 18px;
|
||||||
display: none;
|
padding: 13px 24px 9px 24px;
|
||||||
width: 90%;
|
|
||||||
padding: 13px 0 9px 10%;
|
|
||||||
background-color: #E0E0E0;
|
|
||||||
color: #424242;
|
color: #424242;
|
||||||
|
width: 120px;
|
||||||
|
max-width: 120px;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
.permission.canEdit .metacodeTitle {
|
.permission.canEdit .metacodeTitle {
|
||||||
cursor:pointer;
|
cursor:pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.permission.canEdit .expandMetacodeSelect {
|
.permission.canEdit .expandMetacodeSelect {
|
||||||
position: absolute;
|
position: relative;
|
||||||
top: 16px;
|
top: 2px;
|
||||||
right: 16px;
|
left: 4px;
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
background-image: url(<%= asset_data_uri('arrowright_sprite.png') %>);
|
background-image: url(<%= asset_data_uri('arrowright_sprite.png') %>);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: 0 -32px;
|
background-position: 0 -32px;
|
||||||
|
display: inline-block;
|
||||||
|
-webkit-transform: rotate(90deg);
|
||||||
|
transform: rotate(90deg);
|
||||||
}
|
}
|
||||||
.permission.canEdit .minimize .expandMetacodeSelect {
|
.permission.canEdit .minimize .expandMetacodeSelect {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .metacodeImage {
|
.CardOnGraph .metacodeName {
|
||||||
cursor:move;
|
display: inline-block;
|
||||||
width:46px;
|
|
||||||
height:46px;
|
|
||||||
position:absolute;
|
|
||||||
left:-23px;
|
|
||||||
top:0;
|
|
||||||
background-size:46px 46px;
|
|
||||||
background-position:0 0;
|
|
||||||
background-repeat:no-repeat;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#metacodeOptions {
|
|
||||||
display:none;
|
|
||||||
}
|
|
||||||
.CardOnGraph .metacodeSelect {
|
.CardOnGraph .metacodeSelect {
|
||||||
display:none;
|
display:none;
|
||||||
width:auto;
|
width:auto;
|
||||||
z-index: 2;
|
z-index: 2;
|
||||||
position: absolute;
|
|
||||||
background: #EAEAEA;
|
background: #EAEAEA;
|
||||||
left: 300px;
|
|
||||||
white-space: nowrap;
|
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 {
|
.CardOnGraph .metacodeSelect ul {
|
||||||
position: relative;
|
position: relative;
|
||||||
|
@ -592,15 +609,14 @@ background-color: #E0E0E0;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .hoverForTip:hover .tip, .mapCard .hoverForTip:hover .tip, #mapContribs:hover .tip {
|
.CardOnGraph .hoverForTip:hover .tip, #mapContribs:hover .tip {
|
||||||
display:block;
|
display:block;
|
||||||
}
|
}
|
||||||
.CardOnGraph .tip, .mapCard .tip {
|
.CardOnGraph .tip {
|
||||||
display:none;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
background: black;
|
background: $mid-gray;
|
||||||
top: 35px;
|
top: 35px;
|
||||||
left: 0;
|
right: 0;
|
||||||
color: white;
|
color: white;
|
||||||
border-radius: 4px;
|
border-radius: 4px;
|
||||||
font-size:15px !important;
|
font-size:15px !important;
|
||||||
|
@ -609,21 +625,18 @@ background-color: #E0E0E0;
|
||||||
z-index:100;
|
z-index:100;
|
||||||
}
|
}
|
||||||
|
|
||||||
#embedlyLink {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
#embedlyLinkLoader {
|
#embedlyLinkLoader {
|
||||||
margin: 0 auto;
|
margin: 0 auto;
|
||||||
width: 28px;
|
width: 28px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.CardOnGraph .attachments {
|
.CardOnGraph .link-adder {
|
||||||
border-top: 1px solid #BDBDBD;
|
|
||||||
width:100%;
|
width:100%;
|
||||||
height:47px;
|
height:47px;
|
||||||
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
.attachments a {
|
.link-adder a {
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
|
@ -682,9 +695,9 @@ background-color: #E0E0E0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#addLinkInput input{
|
#addLinkInput input{
|
||||||
padding: 9px 7px 9px 31px;
|
padding: 9px 27px 9px 31px;
|
||||||
height: 12px;
|
height: 12px;
|
||||||
width: 198px;
|
width: 210px;
|
||||||
margin: 0 0 0 0;
|
margin: 0 0 0 0;
|
||||||
border: none;
|
border: none;
|
||||||
outline: none;
|
outline: none;
|
||||||
|
@ -738,7 +751,6 @@ font-family: 'din-regular', helvetica, sans-serif;
|
||||||
-moz-border-radius-bottomright: 8px;
|
-moz-border-radius-bottomright: 8px;
|
||||||
-webkit-border-bottom-right-radius: 8px;
|
-webkit-border-bottom-right-radius: 8px;
|
||||||
border-bottom-right-radius: 8px;
|
border-bottom-right-radius: 8px;
|
||||||
display: none;
|
|
||||||
margin: 8px;
|
margin: 8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -825,10 +837,10 @@ font-family: 'din-regular', helvetica, sans-serif;
|
||||||
line-height: 16px;
|
line-height: 16px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.canEdit #edit_synapse_desc:hover {
|
.canEdit span.titleWrapper:hover {
|
||||||
background-image: url(<%= asset_data_uri('edit.png') %>);
|
background-image: url(<%= asset_data_uri('edit.png') %>);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: 164px center;
|
background-position: 95% 95%;
|
||||||
cursor: text;
|
cursor: text;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -952,160 +964,14 @@ font-family: 'din-regular', helvetica, sans-serif;
|
||||||
background-position: 0 -24px;
|
background-position: 0 -24px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Map Cards */
|
|
||||||
|
|
||||||
.map {
|
|
||||||
display:inline-block;
|
|
||||||
width:220px;
|
|
||||||
height:340px;
|
|
||||||
font-size: 12px;
|
|
||||||
text-align: left;
|
|
||||||
overflow: visible;
|
|
||||||
background: #e8e8e8;
|
|
||||||
border-radius:2px;
|
|
||||||
margin:16px 16px 16px 19px;
|
|
||||||
box-shadow: 0px 3px 3px rgba(0,0,0,0.23), 0 3px 3px rgba(0,0,0,0.16);
|
|
||||||
}
|
|
||||||
.map:hover {
|
|
||||||
background: #dcdcdc;
|
|
||||||
}
|
|
||||||
.map.newMap {
|
|
||||||
float: left;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.map.newMap a {
|
|
||||||
height: 340px;
|
|
||||||
display: block;
|
|
||||||
position: relative;
|
|
||||||
}
|
|
||||||
.newMap .newMapImage {
|
|
||||||
display: block;
|
|
||||||
width: 72px;
|
|
||||||
height: 72px;
|
|
||||||
background-image: url("<%= asset_data_uri('newmap_sprite.png') %>");
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
background-position: 0 0;
|
|
||||||
position: absolute;
|
|
||||||
left: 50%;
|
|
||||||
margin-left: -36px;
|
|
||||||
top: 50%;
|
|
||||||
margin-top: -36px;
|
|
||||||
}
|
|
||||||
.map:hover .newMapImage {
|
|
||||||
background-position: 0 -72px;
|
|
||||||
}
|
|
||||||
.newMap span {
|
|
||||||
font-family: 'din-regular', sans-serif;
|
|
||||||
font-size: 18px;
|
|
||||||
line-height: 22px;
|
|
||||||
text-align: center;
|
|
||||||
display: block;
|
|
||||||
padding-top: 220px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mapCard {
|
|
||||||
display: -webkit-box; /* OLD - iOS 6-, Safari 3.1-6 */
|
|
||||||
display: -moz-box; /* OLD - Firefox 19- (buggy but mostly works) */
|
|
||||||
display: -ms-flexbox; /* TWEENER - IE 10 */
|
|
||||||
display: -webkit-flex; /* NEW - Chrome */
|
|
||||||
display: flex; /* NEW, Spec - Opera 12.1, Firefox 20+ */
|
|
||||||
-webkit-box-orient: vertical;
|
|
||||||
-moz-box-orient: vertical;
|
|
||||||
-webkit-box-direction: normal;
|
|
||||||
-moz-box-direction: normal;
|
|
||||||
-ms-flex-direction: column;
|
|
||||||
-webkit-flex-direction: column;
|
|
||||||
flex-direction: column;
|
|
||||||
position:relative;
|
|
||||||
width:100%;
|
|
||||||
height:308px;
|
|
||||||
padding: 16px 0;
|
|
||||||
color: #424242;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mapCard .title {
|
|
||||||
word-wrap: break-word;
|
|
||||||
font-size:18px;
|
|
||||||
line-height:22px;
|
|
||||||
height: 44px;
|
|
||||||
display:block;
|
|
||||||
padding: 0 16px;
|
|
||||||
text-align: center;
|
|
||||||
-webkit-box-flex: none; /* OLD - iOS 6-, Safari 3.1-6 */
|
|
||||||
-moz-box-flex: none; /* OLD - Firefox 19- */
|
|
||||||
-webkit-flex: none; /* Chrome */
|
|
||||||
-ms-flex: none; /* IE 10 */
|
|
||||||
flex: none; /* NEW, Spec - Opera 12.1, Firefox 20+ */
|
|
||||||
font-family: 'din-regular', sans-serif;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mapCard .mapScreenshot {
|
|
||||||
width: 188px;
|
|
||||||
height: 126px;
|
|
||||||
padding: 8px 16px;
|
|
||||||
}
|
|
||||||
.mapCard .mapScreenshot img {
|
|
||||||
width: 188px;
|
|
||||||
height: 126px;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mapCard .scroll {
|
|
||||||
display:block;
|
|
||||||
-webkit-box-flex: 1; /* OLD - iOS 6-, Safari 3.1-6 */
|
|
||||||
-moz-box-flex: 1; /* OLD - Firefox 19- */
|
|
||||||
-webkit-flex: 1; /* Chrome */
|
|
||||||
-ms-flex: 1; /* IE 10 */
|
|
||||||
flex: 1; /* NEW, Spec - Opera 12.1, Firefox 20+ */
|
|
||||||
padding:0 16px 8px;
|
|
||||||
font-family: helvetica, sans-serif;
|
|
||||||
font-style: italic;
|
|
||||||
font-size: 12px;
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
.mCS_no_scrollbar {
|
|
||||||
padding-right: 5px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mapCard .mapMetadata {
|
|
||||||
font-family: 'din-regular', sans-serif;
|
|
||||||
font-size: 12px;
|
|
||||||
position:relative;
|
|
||||||
border-top: 1px solid #BDBDBD;
|
|
||||||
-webkit-box-flex: none; /* OLD - iOS 6-, Safari 3.1-6 */
|
|
||||||
-moz-box-flex: none; /* OLD - Firefox 19- */
|
|
||||||
-webkit-flex: none; /* Chrome */
|
|
||||||
-ms-flex: none; /* IE 10 */
|
|
||||||
flex: none; /* NEW, Spec - Opera 12.1, Firefox 20+ */
|
|
||||||
}
|
|
||||||
|
|
||||||
.mapCard .metadataSection {
|
|
||||||
padding: 8px 16px 0 16px;
|
|
||||||
width: 78px;
|
|
||||||
float: left;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mapPermission {
|
|
||||||
font-family: 'din-medium', sans-serif;
|
|
||||||
}
|
|
||||||
.cCountColor {
|
|
||||||
font-family: 'din-medium', sans-serif;
|
|
||||||
color: #DB5D5D;
|
|
||||||
}
|
|
||||||
.tCountColor {
|
|
||||||
font-family: 'din-medium', sans-serif;
|
|
||||||
color: #4FC059;
|
|
||||||
}
|
|
||||||
.sCountColor {
|
|
||||||
font-family: 'din-medium', sans-serif;
|
|
||||||
color: #DAB539;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* mapper card */
|
/* mapper card */
|
||||||
|
|
||||||
.mapper {
|
.mapper {
|
||||||
float: left;
|
display: inline-block;
|
||||||
|
vertical-align: bottom;
|
||||||
width:220px;
|
width:220px;
|
||||||
height:340px;
|
height:340px;
|
||||||
font-size: 12px;
|
font-size: 12px;
|
||||||
|
@ -1113,7 +979,7 @@ font-family: 'din-regular', helvetica, sans-serif;
|
||||||
overflow: visible;
|
overflow: visible;
|
||||||
background: #E0E0E0;
|
background: #E0E0E0;
|
||||||
border-radius:2px;
|
border-radius:2px;
|
||||||
margin:16px 16px 16px 19px;
|
margin:16px;
|
||||||
box-shadow: 0px 3px 3px rgba(0,0,0,0.23), 0 3px 3px rgba(0,0,0,0.16);
|
box-shadow: 0px 3px 3px rgba(0,0,0,0.23), 0 3px 3px rgba(0,0,0,0.16);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1137,10 +1003,10 @@ font-family: 'din-regular', helvetica, sans-serif;
|
||||||
font-size: 24px;
|
font-size: 24px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
margin-top: 24px;
|
margin-top: 24px;
|
||||||
padding: 0 16px;
|
padding: 0 5%;
|
||||||
white-space: nowrap;
|
white-space: nowrap;
|
||||||
text-overflow: ellipsis;
|
text-overflow: ellipsis;
|
||||||
width: 189px;
|
width: 90%;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,9 @@
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
box-sizing: border-box;
|
||||||
|
padding-top: 92px;
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*.animations {
|
/*.animations {
|
||||||
|
@ -44,23 +47,9 @@
|
||||||
transition-timing-function: ease-in-out;
|
transition-timing-function: ease-in-out;
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
.mapElement {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.mapPage .mapElement, .topicPage .mapElement {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.mapPage .mapElementHidden {
|
|
||||||
display:none;
|
|
||||||
}
|
|
||||||
.topicPage .starMap {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* loading */
|
/* loading */
|
||||||
|
|
||||||
#loading {
|
#loading {
|
||||||
display: none;
|
|
||||||
width: 28px;
|
width: 28px;
|
||||||
height: 28px;
|
height: 28px;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
@ -179,10 +168,14 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.upperRightMapButtons {
|
.upperRightMapButtons {
|
||||||
top: -42px; /* puts it just offscreen */
|
right: 138px;
|
||||||
|
padding-right: 7px;
|
||||||
|
border-right: 1px solid #747474;
|
||||||
}
|
}
|
||||||
.mapPage .upperRightMapButtons, .topicPage .upperRightMapButtons {
|
.unauthenticated .upperRightMapButtons {
|
||||||
top: 0;
|
right: 115px;
|
||||||
|
padding-right: 0;
|
||||||
|
border-right: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.upperRightIcon {
|
.upperRightIcon {
|
||||||
|
@ -192,30 +185,47 @@
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebarFilterIcon {
|
.sidebarFilterIcon {
|
||||||
background-position: -64px 0;
|
background-position: -32px 0;
|
||||||
}
|
}
|
||||||
.sidebarForkIcon {
|
.sidebarForkIcon {
|
||||||
background-position: -96px 0;
|
background-position: -64px 0;
|
||||||
}
|
}
|
||||||
.addMap {
|
.addMap {
|
||||||
|
background-position: -96px 0;
|
||||||
|
}
|
||||||
|
.notificationsIcon {
|
||||||
background-position: -128px 0;
|
background-position: -128px 0;
|
||||||
margin-right:10px;
|
margin-right: 10px; // make it look more natural next to the account menu icon
|
||||||
|
}
|
||||||
|
.notificationsIcon:hover {
|
||||||
|
background-position: -128px -32px;
|
||||||
|
}
|
||||||
|
.importDialog:hover {
|
||||||
|
background-position: 0 -32px;
|
||||||
}
|
}
|
||||||
.sidebarFilterIcon:hover {
|
.sidebarFilterIcon:hover {
|
||||||
background-position: -64px -32px;
|
background-position: -32px -32px;
|
||||||
}
|
}
|
||||||
.sidebarForkIcon:hover {
|
.sidebarForkIcon:hover {
|
||||||
background-position: -96px -32px;
|
background-position: -64px -32px;
|
||||||
}
|
}
|
||||||
.addMap:hover {
|
.addMap:hover {
|
||||||
background-position: -128px -32px;
|
background-position: -96px -32px;
|
||||||
margin-right:10px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* end upperRightUI */
|
/* end upperRightUI */
|
||||||
|
|
||||||
|
/* map wrapper */
|
||||||
|
.mapWrapper {
|
||||||
|
position:absolute;
|
||||||
|
width: 100%;
|
||||||
|
height: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* end map wrapper */
|
||||||
|
|
||||||
/* yield */
|
/* yield */
|
||||||
|
|
||||||
|
@ -336,22 +346,15 @@
|
||||||
|
|
||||||
/* infoAndHelp */
|
/* infoAndHelp */
|
||||||
|
|
||||||
.mapPage .infoAndHelp, .topicPage .infoAndHelp {
|
.openCheatsheet .tooltipsAbove {
|
||||||
right: 70px;
|
|
||||||
}
|
|
||||||
.mapPage .openCheatsheet .tooltipsAbove, .topicPage .openCheatsheet .tooltipsAbove {
|
|
||||||
right: 1px;
|
right: 1px;
|
||||||
left: auto;
|
left: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.unauthenticated .homePage .infoAndHelp {
|
|
||||||
display:none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.infoAndHelp {
|
.infoAndHelp {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 20px;
|
bottom: 20px;
|
||||||
right: 20px;
|
right: 70px;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
width: auto;
|
width: auto;
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
|
@ -372,22 +375,13 @@
|
||||||
}
|
}
|
||||||
.mapInfoIcon {
|
.mapInfoIcon {
|
||||||
position: relative;
|
position: relative;
|
||||||
top: 56px; /* puts it just offscreen */
|
background-image: url(<%= asset_path('mapinfo_sprite.png') %>);
|
||||||
background-image: url(<%= asset_path('mapinfo_sprite.png') %>);
|
background-repeat:no-repeat;
|
||||||
background-repeat:no-repeat;
|
|
||||||
}
|
}
|
||||||
.mapInfoIcon:hover {
|
.mapInfoIcon:hover {
|
||||||
background-position: 0 -32px;
|
background-position: 0 -32px;
|
||||||
}
|
}
|
||||||
.mapPage .mapInfoIcon {
|
|
||||||
top: 0;
|
|
||||||
}
|
|
||||||
.importDialog {
|
|
||||||
background-image: url(<%= asset_path('import.png') %>);
|
|
||||||
background-position: 0 0;
|
|
||||||
background-repeat: no-repeat;
|
|
||||||
width: 32px;
|
|
||||||
}
|
|
||||||
.starMap {
|
.starMap {
|
||||||
background-image: url(<%= asset_path('starmap_sprite.png') %>);
|
background-image: url(<%= asset_path('starmap_sprite.png') %>);
|
||||||
background-position: 0 0;
|
background-position: 0 0;
|
||||||
|
@ -404,9 +398,6 @@
|
||||||
background-position: 0 0;
|
background-position: 0 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.unauthenticated .mapPage .starMap {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
/* end infoAndHelp */
|
/* end infoAndHelp */
|
||||||
|
|
||||||
|
|
||||||
|
@ -415,24 +406,17 @@
|
||||||
.mapControls {
|
.mapControls {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
bottom: 24px;
|
bottom: 24px;
|
||||||
right:-32px; /* puts it just offscreen */
|
right:24px;
|
||||||
width:32px;
|
width:32px;
|
||||||
z-index: 3;
|
z-index: 3;
|
||||||
}
|
}
|
||||||
.mapPage .mapControls, .topicPage .mapControls {
|
|
||||||
right: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.topicPage .zoomExtents {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
|
|
||||||
.mapControl {
|
.mapControl {
|
||||||
width:32px;
|
width:32px;
|
||||||
height:32px;
|
height:32px;
|
||||||
background-color: #424242;
|
background-color: #424242;
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
background-position: 0 0;
|
background-position: 0 0;
|
||||||
cursor:pointer;
|
cursor:pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -440,19 +424,6 @@
|
||||||
z-index: 4;
|
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 {
|
.zoomExtents {
|
||||||
margin-bottom:5px;
|
margin-bottom:5px;
|
||||||
border-radius: 2px;
|
border-radius: 2px;
|
||||||
|
@ -463,8 +434,8 @@
|
||||||
background-position: -32px 0;
|
background-position: -32px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.zoomExtents:hover .tooltips, .zoomIn:hover .tooltips, .zoomOut:hover .tooltips, .takeScreenshot:hover .tooltips, .sidebarFilterIcon:hover .tooltipsUnder, .sidebarForkIcon: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 .tooltipsAbove, .starMap:hover .tooltipsAbove, .openMetacodeSwitcher:hover .tooltipsAbove, .pinCarousel:not(.isPinned):hover .tooltipsAbove.helpPin, .pinCarousel.isPinned:hover .tooltipsAbove.helpUnpin {
|
.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;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -520,9 +491,16 @@
|
||||||
font-style: normal;
|
font-style: normal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.importDialog .tooltipsUnder {
|
||||||
|
left: -22px;
|
||||||
|
}
|
||||||
|
|
||||||
.sidebarFilterIcon .tooltipsUnder {
|
.sidebarFilterIcon .tooltipsUnder {
|
||||||
margin-left: -4px;
|
margin-left: -4px;
|
||||||
}
|
}
|
||||||
|
.notificationsIcon .tooltipsUnder {
|
||||||
|
left: -20px;
|
||||||
|
}
|
||||||
|
|
||||||
.sidebarForkIcon .tooltipsUnder {
|
.sidebarForkIcon .tooltipsUnder {
|
||||||
margin-left: -34px;
|
margin-left: -34px;
|
||||||
|
@ -578,16 +556,12 @@
|
||||||
left: -8px;
|
left: -8px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.openCheatsheet .tooltipsAbove {
|
|
||||||
left: -4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.sidebarAccountIcon .tooltipsUnder {
|
.sidebarAccountIcon .tooltipsUnder {
|
||||||
margin-left: -12px;
|
margin-left: -12px;
|
||||||
margin-top: 40px;
|
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: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 57%;
|
top: 57%;
|
||||||
|
@ -600,7 +574,12 @@
|
||||||
border-bottom: 5px solid transparent;
|
border-bottom: 5px solid transparent;
|
||||||
}
|
}
|
||||||
|
|
||||||
.sidebarFilterIcon div:after, .sidebarForkIcon div:after, .addMap div:after, .sidebarAccountIcon .tooltipsUnder:after {
|
.addMap div:after,
|
||||||
|
.importDialog div:after,
|
||||||
|
.sidebarForkIcon div:after,
|
||||||
|
.sidebarFilterIcon div:after,
|
||||||
|
.notificationsIcon div:after,
|
||||||
|
.sidebarAccountIcon .tooltipsUnder:after {
|
||||||
content: '';
|
content: '';
|
||||||
position: absolute;
|
position: absolute;
|
||||||
right: 40%;
|
right: 40%;
|
||||||
|
@ -611,9 +590,15 @@
|
||||||
border-left: 5px solid transparent;
|
border-left: 5px solid transparent;
|
||||||
border-right: 5px solid transparent;
|
border-right: 5px solid transparent;
|
||||||
}
|
}
|
||||||
|
.notificationsIcon .unread-notifications-dot:after {
|
||||||
|
content: none;
|
||||||
|
}
|
||||||
.sidebarFilterIcon div:after {
|
.sidebarFilterIcon div:after {
|
||||||
right: 37% !important;
|
right: 37% !important;
|
||||||
}
|
}
|
||||||
|
.notificationsIcon div:after {
|
||||||
|
right: 46% !important;
|
||||||
|
}
|
||||||
|
|
||||||
.mapInfoIcon div:after, .openCheatsheet div:after, .starMap div:after, .openMetacodeSwitcher div:after, .pinCarousel div:after {
|
.mapInfoIcon div:after, .openCheatsheet div:after, .starMap div:after, .openMetacodeSwitcher div:after, .pinCarousel div:after {
|
||||||
content: '';
|
content: '';
|
||||||
|
@ -651,20 +636,22 @@
|
||||||
|
|
||||||
/* explore maps */
|
/* explore maps */
|
||||||
|
|
||||||
#explore {
|
#react-app {
|
||||||
display: none;
|
position: absolute;
|
||||||
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#exploreMaps {
|
#exploreMaps {
|
||||||
padding: 0 5%;
|
|
||||||
position: absolute;
|
position: absolute;
|
||||||
width: 90%;
|
|
||||||
height: 100%;
|
height: 100%;
|
||||||
|
width: 100%;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
#exploreMaps > div {
|
#exploreMaps > div {
|
||||||
margin-top: 110px;
|
margin: 110px auto 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.button.loadMore {
|
.button.loadMore {
|
||||||
|
@ -672,23 +659,28 @@
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.appsPage #exploreMapsHeader {
|
.requestInviteHeader {
|
||||||
display: block;
|
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;
|
position: absolute;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.exploreMapsBar {
|
.navBarContainer {
|
||||||
z-index:2;
|
z-index:2;
|
||||||
background-color:#FAFAFA;
|
background-color:#FAFAFA;
|
||||||
height: 42px;
|
height: 42px;
|
||||||
padding-top: 52px;
|
padding-top: 52px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.exploreMapsMenu {
|
.navBarMenu {
|
||||||
display: block;
|
display: block;
|
||||||
width: 100%;
|
width: 100%;
|
||||||
height:42px;
|
height:42px;
|
||||||
|
@ -697,30 +689,29 @@
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
.exploreMapsCenter {
|
.navBarCenter {
|
||||||
display: block;
|
display: block;
|
||||||
}
|
}
|
||||||
|
|
||||||
.exploreMapsButton {
|
.navBarButton {
|
||||||
color: #757575;
|
color: #757575;
|
||||||
cursor: default;
|
cursor: default;
|
||||||
font-weight: normal;
|
font-weight: normal;
|
||||||
font-family: 'din-medium';
|
font-family: 'din-medium';
|
||||||
font-size: 14px;
|
font-size: 14px;
|
||||||
height: 14px;
|
padding: 0 8px;
|
||||||
padding: 14px 8px 12px 40px;
|
border-bottom: 2px solid rgba(0,0,0,0);
|
||||||
border-bottom: 2px solid rgba(0,0,0,0);
|
|
||||||
display: inline-block;
|
display: inline-block;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
position:relative;
|
position:relative;
|
||||||
}
|
}
|
||||||
.exploreMapsButton:hover, .exploreMapsButton.active {
|
.navBarButton:hover, .navBarButton.active {
|
||||||
text-decoration: none;
|
text-decoration: none;
|
||||||
color: #424242;
|
color: #424242;
|
||||||
border-bottom: 2px solid #00BCD4;
|
border-bottom: 2px solid #00BCD4;
|
||||||
}
|
}
|
||||||
|
|
||||||
.exploreMapsButton.mapperButton {
|
.navBarButton.mapperButton {
|
||||||
height: 40px;
|
height: 40px;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
@ -737,49 +728,71 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
.exploreMapsButton .exploreMapsIcon {
|
.navBarButton .navBarIcon {
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
width:32px;
|
width:32px;
|
||||||
height:32px;
|
height:32px;
|
||||||
position:absolute;
|
margin-top:5px;
|
||||||
top:5px;
|
margin-left:5px;
|
||||||
left:5px;
|
margin-right: 5px;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: top;
|
||||||
}
|
}
|
||||||
.exploreMapsCenter .myMaps .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;
|
||||||
|
}
|
||||||
|
.navBarCenter .myMaps .navBarIcon {
|
||||||
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
|
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
|
||||||
background-position: -32px 0;
|
background-position: -32px 0;
|
||||||
}
|
}
|
||||||
.exploreMapsCenter .sharedMaps .exploreMapsIcon {
|
.navBarCenter .sharedMaps .navBarIcon {
|
||||||
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
|
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
|
||||||
background-position: -128px 0;
|
background-position: -128px 0;
|
||||||
}
|
}
|
||||||
.exploreMapsCenter .activeMaps .exploreMapsIcon {
|
.navBarCenter .activeMaps .navBarIcon {
|
||||||
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
|
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
|
||||||
background-position: 0 0;
|
background-position: 0 0;
|
||||||
}
|
}
|
||||||
.exploreMapsCenter .featuredMaps .exploreMapsIcon {
|
.navBarCenter .featuredMaps .navBarIcon {
|
||||||
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
|
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
|
||||||
background-position: -96px 0;
|
background-position: -96px 0;
|
||||||
}
|
}
|
||||||
.exploreMapsCenter .starredMaps .exploreMapsIcon {
|
.navBarCenter .starredMaps .navBarIcon {
|
||||||
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
|
background-image: url(<%= asset_path 'exploremaps_sprite.png' %>);
|
||||||
background-position: -96px 0;
|
background-position: -96px 0;
|
||||||
}
|
}
|
||||||
.myMaps:hover .exploreMapsIcon, .myMaps.active .exploreMapsIcon {
|
.navBarCenter .notificationsLink .navBarIcon {
|
||||||
|
background-image: url(<%= asset_path 'topright_sprite.png' %>);
|
||||||
|
background-position: -128px 0;
|
||||||
|
}
|
||||||
|
.authedApps:hover .navBarIcon, .authedApps.active .navBarIcon {
|
||||||
|
background-position-x: -32px;
|
||||||
|
}
|
||||||
|
.myMaps:hover .navBarIcon, .myMaps.active .navBarIcon {
|
||||||
background-position: -32px -32px;
|
background-position: -32px -32px;
|
||||||
}
|
}
|
||||||
.activeMaps:hover .exploreMapsIcon, .activeMaps.active .exploreMapsIcon {
|
.activeMaps:hover .navBarIcon, .activeMaps.active .navBarIcon {
|
||||||
background-position: 0 -32px;
|
background-position: 0 -32px;
|
||||||
}
|
}
|
||||||
.featuredMaps:hover .exploreMapsIcon, .featuredMaps.active .exploreMapsIcon {
|
.featuredMaps:hover .navBarIcon, .featuredMaps.active .navBarIcon {
|
||||||
background-position: -96px -32px;
|
background-position: -96px -32px;
|
||||||
}
|
}
|
||||||
.starredMaps:hover .exploreMapsIcon, .starredMaps.active .exploreMapsIcon {
|
.starredMaps:hover .navBarIcon, .starredMaps.active .navBarIcon {
|
||||||
background-position: -96px -32px;
|
background-position: -96px -32px;
|
||||||
}
|
}
|
||||||
.sharedMaps:hover .exploreMapsIcon, .sharedMaps.active .exploreMapsIcon {
|
.sharedMaps:hover .navBarIcon, .sharedMaps.active .navBarIcon {
|
||||||
background-position: -128px -32px;
|
background-position: -128px -32px;
|
||||||
}
|
}
|
||||||
|
.notificationsLink:hover .navBarIcon, .notificationsLink.active .navBarIcon {
|
||||||
|
background-position-y: -32px;
|
||||||
|
}
|
||||||
|
|
||||||
.mapsWrapper {
|
.mapsWrapper {
|
||||||
/*overflow-y: auto; */
|
/*overflow-y: auto; */
|
||||||
|
@ -795,7 +808,6 @@
|
||||||
height: 80px;
|
height: 80px;
|
||||||
font-family: 'din-regular', helvetica, sans-serif;
|
font-family: 'din-regular', helvetica, sans-serif;
|
||||||
font-size: 32px;
|
font-size: 32px;
|
||||||
display: none;
|
|
||||||
text-align: center;
|
text-align: center;
|
||||||
color: #999999;
|
color: #999999;
|
||||||
z-index: 0;
|
z-index: 0;
|
||||||
|
@ -811,7 +823,6 @@
|
||||||
/* toast */
|
/* toast */
|
||||||
|
|
||||||
.toast {
|
.toast {
|
||||||
display: none;
|
|
||||||
position: fixed;
|
position: fixed;
|
||||||
bottom: 20px;
|
bottom: 20px;
|
||||||
left: 20px;
|
left: 20px;
|
||||||
|
|
263
app/assets/stylesheets/emoji-mart-0.3.5.css
Normal file
263
app/assets/stylesheets/emoji-mart-0.3.5.css
Normal file
|
@ -0,0 +1,263 @@
|
||||||
|
.emoji-mart,
|
||||||
|
.emoji-mart * {
|
||||||
|
box-sizing: border-box;
|
||||||
|
line-height: 1.15;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart {
|
||||||
|
font-family: -apple-system, BlinkMacSystemFont, "Helvetica Neue", sans-serif;
|
||||||
|
font-size: 16px;
|
||||||
|
display: inline-block;
|
||||||
|
color: #222427;
|
||||||
|
border: 1px solid #d9d9d9;
|
||||||
|
border-radius: 5px;
|
||||||
|
background: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart .emoji-mart-emoji {
|
||||||
|
padding: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-bar:first-child {
|
||||||
|
border-top-left-radius: 5px;
|
||||||
|
border-top-right-radius: 5px;
|
||||||
|
}
|
||||||
|
.emoji-mart-bar:last-child {
|
||||||
|
border-bottom-left-radius: 5px;
|
||||||
|
border-bottom-right-radius: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-anchors {
|
||||||
|
display: flex;
|
||||||
|
justify-content: space-between;
|
||||||
|
padding: 0 6px;
|
||||||
|
color: #858585;
|
||||||
|
line-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-anchor {
|
||||||
|
position: relative;
|
||||||
|
flex: 1;
|
||||||
|
text-align: center;
|
||||||
|
padding: 12px 4px;
|
||||||
|
overflow: hidden;
|
||||||
|
transition: color .1s ease-out;
|
||||||
|
}
|
||||||
|
.emoji-mart-anchor:hover,
|
||||||
|
.emoji-mart-anchor-selected {
|
||||||
|
color: #464646;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-anchor-selected .emoji-mart-anchor-bar {
|
||||||
|
bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-anchor-bar {
|
||||||
|
position: absolute;
|
||||||
|
bottom: -3px; left: 0;
|
||||||
|
width: 100%; height: 3px;
|
||||||
|
background-color: #464646;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-anchors i {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%;
|
||||||
|
max-width: 22px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-anchors svg {
|
||||||
|
fill: currentColor;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-scroll {
|
||||||
|
overflow-y: scroll;
|
||||||
|
height: 270px;
|
||||||
|
padding: 0 6px 6px 6px;
|
||||||
|
border: solid #d9d9d9;
|
||||||
|
border-width: 1px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-search {
|
||||||
|
font-size: 16px;
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
padding: .2em .6em;
|
||||||
|
margin-top: 6px;
|
||||||
|
border-radius: 25px;
|
||||||
|
border: 1px solid #d9d9d9;
|
||||||
|
outline: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-category .emoji-mart-emoji span {
|
||||||
|
z-index: 1;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-category .emoji-mart-emoji:hover:before {
|
||||||
|
z-index: 0;
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 0; left: 0;
|
||||||
|
width: 100%; height: 100%;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
border-radius: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-category-label {
|
||||||
|
z-index: 2;
|
||||||
|
position: relative;
|
||||||
|
position: -webkit-sticky;
|
||||||
|
top: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-category-label span {
|
||||||
|
display: block;
|
||||||
|
width: 100%;
|
||||||
|
font-weight: 500;
|
||||||
|
padding: 5px 6px;
|
||||||
|
background-color: #fff;
|
||||||
|
background-color: rgba(255, 255, 255, .95);
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-emoji {
|
||||||
|
position: relative;
|
||||||
|
display: inline-block;
|
||||||
|
font-size: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-no-results {
|
||||||
|
font-size: 14px;
|
||||||
|
text-align: center;
|
||||||
|
padding-top: 70px;
|
||||||
|
color: #858585;
|
||||||
|
}
|
||||||
|
.emoji-mart-no-results span {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-preview {
|
||||||
|
position: relative;
|
||||||
|
height: 70px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-preview-emoji,
|
||||||
|
.emoji-mart-preview-data,
|
||||||
|
.emoji-mart-preview-skins {
|
||||||
|
position: absolute;
|
||||||
|
top: 50%;
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-preview-emoji {
|
||||||
|
left: 12px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-preview-data {
|
||||||
|
left: 68px; right: 12px;
|
||||||
|
word-break: break-word;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-preview-skins {
|
||||||
|
right: 30px;
|
||||||
|
text-align: right;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-preview-name {
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-preview-shortname {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #888;
|
||||||
|
}
|
||||||
|
.emoji-mart-preview-shortname + .emoji-mart-preview-shortname,
|
||||||
|
.emoji-mart-preview-shortname + .emoji-mart-preview-emoticon,
|
||||||
|
.emoji-mart-preview-emoticon + .emoji-mart-preview-emoticon {
|
||||||
|
margin-left: .5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-preview-emoticon {
|
||||||
|
font-size: 11px;
|
||||||
|
color: #bbb;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-title span {
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-title .emoji-mart-emoji {
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-title-label {
|
||||||
|
color: #999A9C;
|
||||||
|
font-size: 26px;
|
||||||
|
font-weight: 300;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-skin-swatches {
|
||||||
|
font-size: 0;
|
||||||
|
padding: 2px 0;
|
||||||
|
border: 1px solid #d9d9d9;
|
||||||
|
border-radius: 12px;
|
||||||
|
background-color: #fff;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-skin-swatches-opened .emoji-mart-skin-swatch {
|
||||||
|
width: 16px;
|
||||||
|
padding: 0 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-skin-swatches-opened .emoji-mart-skin-swatch-selected:after {
|
||||||
|
opacity: .75;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-skin-swatch {
|
||||||
|
display: inline-block;
|
||||||
|
width: 0;
|
||||||
|
vertical-align: middle;
|
||||||
|
transition-property: width, padding;
|
||||||
|
transition-duration: .125s;
|
||||||
|
transition-timing-function: ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-skin-swatch:nth-child(1) { transition-delay: 0 }
|
||||||
|
.emoji-mart-skin-swatch:nth-child(2) { transition-delay: .03s }
|
||||||
|
.emoji-mart-skin-swatch:nth-child(3) { transition-delay: .06s }
|
||||||
|
.emoji-mart-skin-swatch:nth-child(4) { transition-delay: .09s }
|
||||||
|
.emoji-mart-skin-swatch:nth-child(5) { transition-delay: .12s }
|
||||||
|
.emoji-mart-skin-swatch:nth-child(6) { transition-delay: .15s }
|
||||||
|
|
||||||
|
.emoji-mart-skin-swatch-selected {
|
||||||
|
position: relative;
|
||||||
|
width: 16px;
|
||||||
|
padding: 0 2px;
|
||||||
|
}
|
||||||
|
.emoji-mart-skin-swatch-selected:after {
|
||||||
|
content: "";
|
||||||
|
position: absolute;
|
||||||
|
top: 50%; left: 50%;
|
||||||
|
width: 4px; height: 4px;
|
||||||
|
margin: -2px 0 0 -2px;
|
||||||
|
background-color: #fff;
|
||||||
|
border-radius: 100%;
|
||||||
|
pointer-events: none;
|
||||||
|
opacity: 0;
|
||||||
|
transition: opacity .2s ease-out;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-skin {
|
||||||
|
display: inline-block;
|
||||||
|
width: 100%; padding-top: 100%;
|
||||||
|
max-width: 12px;
|
||||||
|
border-radius: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emoji-mart-skin-tone-1 { background-color: #ffc93a }
|
||||||
|
.emoji-mart-skin-tone-2 { background-color: #fadcbc }
|
||||||
|
.emoji-mart-skin-tone-3 { background-color: #e0bb95 }
|
||||||
|
.emoji-mart-skin-tone-4 { background-color: #bf8f68 }
|
||||||
|
.emoji-mart-skin-tone-5 { background-color: #9b643d }
|
||||||
|
.emoji-mart-skin-tone-6 { background-color: #594539 }
|
|
@ -1,11 +1,9 @@
|
||||||
/* =USERVOICE ICON DEFINE
|
.unauthenticated .feedback-icon {
|
||||||
--------------------------------------------------------*/
|
|
||||||
|
|
||||||
.unauthenticated .uv-icon {
|
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.uv-icon.uv-bottom-left {
|
.feedback-icon {
|
||||||
|
position: fixed;
|
||||||
background-image: url(<%= asset_data_uri 'feedback_sprite.png' %>);
|
background-image: url(<%= asset_data_uri 'feedback_sprite.png' %>);
|
||||||
background-repeat: no-repeat;
|
background-repeat: no-repeat;
|
||||||
color:#FFFFFF;
|
color:#FFFFFF;
|
||||||
|
@ -20,6 +18,8 @@ div.uv-icon.uv-bottom-left {
|
||||||
opacity: 1;
|
opacity: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
div.uv-icon.uv-bottom-left:hover {
|
.feedback-icon:hover {
|
||||||
background-position: 0 -110px;
|
background-position: 0 -110px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,348 +0,0 @@
|
||||||
.collaborator-video {
|
|
||||||
z-index: 1;
|
|
||||||
position: absolute;
|
|
||||||
width: 150px;
|
|
||||||
height: 150px;
|
|
||||||
cursor: default;
|
|
||||||
color: #FFF;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-receive {
|
|
||||||
position: absolute;
|
|
||||||
width: 160px;
|
|
||||||
padding: 20px 20px 20px 170px;
|
|
||||||
background: #424242;
|
|
||||||
height: 110px;
|
|
||||||
border-top-left-radius: 75px;
|
|
||||||
border-bottom-left-radius: 75px;
|
|
||||||
border-top-right-radius: 2px;
|
|
||||||
border-bottom-right-radius: 2px;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-receive .video-statement {
|
|
||||||
margin-bottom: 10px;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-receive .btn-group .btn-yes {
|
|
||||||
margin-right: 10px;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-receive .btn-group .btn-no {
|
|
||||||
background-color: #c04f4f;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-receive .btn-group .btn-no:hover {
|
|
||||||
background-color: #A54242;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-cutoff {
|
|
||||||
width: 150px;
|
|
||||||
height: 150px;
|
|
||||||
overflow: hidden;
|
|
||||||
border-radius: 75px;
|
|
||||||
z-index: 0;
|
|
||||||
position: relative;
|
|
||||||
-webkit-box-shadow: 0px 6px 3px rgba(0, 0, 0, 0.23), 10px 10px 10px rgba(0, 0, 0, 0.19);
|
|
||||||
-moz-box-shadow: 0px 6px 3px rgba(0, 0, 0, 0.23), 10px 10px 10px rgba(0, 0, 0, 0.19);
|
|
||||||
box-shadow: 0px 6px 3px rgba(0, 0, 0, 0.23), 10px 10px 10px rgba(0, 0, 0, 0.19);
|
|
||||||
}
|
|
||||||
.collaborator-video .video-cutoff video {
|
|
||||||
height: 150px;
|
|
||||||
margin-left: -25px;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-cutoff .collaborator-video-avatar {
|
|
||||||
position: absolute;
|
|
||||||
top: 0;
|
|
||||||
left: 0;
|
|
||||||
-webkit-user-select: none;
|
|
||||||
-khtml-user-select: none;
|
|
||||||
-moz-user-select: none;
|
|
||||||
-o-user-select: none;
|
|
||||||
user-select: none;
|
|
||||||
-webkit-user-drag: none;
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-audio {
|
|
||||||
position: absolute;
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
top: 85%;
|
|
||||||
right: 0px;
|
|
||||||
cursor: pointer;
|
|
||||||
background: url(<%= asset_path 'audio_sprite.png' %>) no-repeat;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-audio:hover {
|
|
||||||
background-position-x: -24px;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-audio.active {
|
|
||||||
background-position-y: -24px;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-video {
|
|
||||||
position: absolute;
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
top: 85%;
|
|
||||||
left: 0px;
|
|
||||||
cursor: pointer;
|
|
||||||
background: url(<%= asset_path 'camera_sprite.png' %>) no-repeat;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-video:hover {
|
|
||||||
background-position-x: -24px;
|
|
||||||
}
|
|
||||||
.collaborator-video .video-video.active {
|
|
||||||
background-position-y: -24px;
|
|
||||||
}
|
|
||||||
.collaborator-video.my-video {
|
|
||||||
left: 30px;
|
|
||||||
top: 72px;
|
|
||||||
}
|
|
||||||
.chat-box {
|
|
||||||
position: relative;
|
|
||||||
display: flex;
|
|
||||||
flex-direction: column;
|
|
||||||
z-index: 1;
|
|
||||||
width: 300px;
|
|
||||||
float: right;
|
|
||||||
height: 100%;
|
|
||||||
background: #424242;
|
|
||||||
box-shadow: -8px 0px 16px 2px rgba(0, 0, 0, 0.23);
|
|
||||||
}
|
|
||||||
.chat-box .chat-button {
|
|
||||||
position: absolute;
|
|
||||||
top: 50%;
|
|
||||||
left: -36px;
|
|
||||||
width: 36px;
|
|
||||||
height: 49px;
|
|
||||||
background: url(<%= asset_path 'junto.png' %>) no-repeat 2px 9px, url(<%= asset_path 'tray_tab.png' %>) no-repeat;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
.chat-box .chat-button.active {
|
|
||||||
background: url(<%= asset_path 'junto_spinner_dark.gif' %>) no-repeat 2px 8px, url(<%= asset_path 'tray_tab.png' %>) no-repeat !important;
|
|
||||||
}
|
|
||||||
.chat-box .chat-button .chat-unread {
|
|
||||||
display: none;
|
|
||||||
background: #DAB539;
|
|
||||||
position: absolute;
|
|
||||||
top: -3px;
|
|
||||||
left: -11px;
|
|
||||||
width: 20px;
|
|
||||||
height: 20px;
|
|
||||||
border-radius: 11px;
|
|
||||||
border: 2px solid #424242;
|
|
||||||
color: #424242;
|
|
||||||
text-align: center;
|
|
||||||
font-size: 12px;
|
|
||||||
font-weight: bold;
|
|
||||||
line-height: 20px;
|
|
||||||
}
|
|
||||||
.chat-box .junto-header {
|
|
||||||
width: 276px;
|
|
||||||
padding: 16px 8px 16px 16px;
|
|
||||||
font-size: 16px;
|
|
||||||
text-align: left;
|
|
||||||
font-weight: bold;
|
|
||||||
background-color: #000000;
|
|
||||||
color: #f5f5f5;
|
|
||||||
box-shadow: 0px 6px 3px rgba(0, 0, 0, 0.23);
|
|
||||||
}
|
|
||||||
.chat-box .junto-header .cursor-toggle {
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
margin-right: 8px;
|
|
||||||
margin-top: -8px;
|
|
||||||
float: right;
|
|
||||||
background: url(<%= asset_path 'cursor_sprite.png' %>) no-repeat;
|
|
||||||
}
|
|
||||||
.chat-box .junto-header .cursor-toggle:hover {
|
|
||||||
background-position-x: -32px;
|
|
||||||
}
|
|
||||||
.chat-box .junto-header .cursor-toggle.active {
|
|
||||||
background-position-y: -32px;
|
|
||||||
}
|
|
||||||
.chat-box .junto-header .video-toggle {
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
margin-right: 10px;
|
|
||||||
margin-top: -8px;
|
|
||||||
float: right;
|
|
||||||
background: url(<%= asset_path 'video_sprite.png' %>) no-repeat;
|
|
||||||
}
|
|
||||||
.chat-box .junto-header .video-toggle:hover {
|
|
||||||
background-position-x: -32px;
|
|
||||||
}
|
|
||||||
.chat-box .junto-header .video-toggle.active {
|
|
||||||
background-position-y: -32px;
|
|
||||||
}
|
|
||||||
.chat-box .participants {
|
|
||||||
width: 100%;
|
|
||||||
min-height: 150px;
|
|
||||||
padding: 16px 0px 16px 0px;
|
|
||||||
text-align: left;
|
|
||||||
color: #f5f5f5;
|
|
||||||
overflow-y: auto;
|
|
||||||
}
|
|
||||||
.chat-box .participants .conversation-live {
|
|
||||||
display: none;
|
|
||||||
padding: 5px 10px 5px 10px;
|
|
||||||
background: #c04f4f;
|
|
||||||
margin: 5px 10px;
|
|
||||||
border-radius: 2px;
|
|
||||||
}
|
|
||||||
.chat-box .participants .conversation-live .call-action {
|
|
||||||
float: right;
|
|
||||||
cursor: pointer;
|
|
||||||
color: #EBFF00;
|
|
||||||
}
|
|
||||||
.chat-box .participants .conversation-live .leave {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.chat-box .participants.is-participating .conversation-live .leave {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.chat-box .participants.is-participating .conversation-live .join {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.chat-box .participants .participant {
|
|
||||||
width: 89%;
|
|
||||||
padding: 8px 8px 2px 8px;
|
|
||||||
color: #f5f5f5;
|
|
||||||
font-family: arial, sans-serif;
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 14px;
|
|
||||||
}
|
|
||||||
.chat-box .participants .participant .chat-participant-image {
|
|
||||||
width: 15%;
|
|
||||||
float: left;
|
|
||||||
overflow: hidden;
|
|
||||||
color: #BBB;
|
|
||||||
padding-top: 2px;
|
|
||||||
}
|
|
||||||
.chat-box .participants .participant .chat-participant-image img {
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
border-radius: 18px;
|
|
||||||
}
|
|
||||||
.chat-box .participants .participant .chat-participant-name {
|
|
||||||
width: 53%;
|
|
||||||
float: left;
|
|
||||||
font-size: 13px;
|
|
||||||
font-weight: bold;
|
|
||||||
margin-top: 12px;
|
|
||||||
padding: 2px 8px 0;
|
|
||||||
text-align: left;
|
|
||||||
}
|
|
||||||
.chat-box .participants .participant.is-self .chat-participant-invite-call,
|
|
||||||
.chat-box .participants .participant.is-self .chat-participant-invite-join {
|
|
||||||
display: none !important;
|
|
||||||
}
|
|
||||||
.chat-box .participants.is-live .participant .chat-participant-invite-call {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.chat-box .participants .participant .chat-participant-invite-join {
|
|
||||||
display: none;
|
|
||||||
}
|
|
||||||
.chat-box .participants.is-live.is-participating .participant:not(.active) .chat-participant-invite-join {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.chat-box .participants .participant .chat-participant-invite-call,
|
|
||||||
.chat-box .participants .participant .chat-participant-invite-join
|
|
||||||
{
|
|
||||||
float: right;
|
|
||||||
background: #4FC059 url(<%= asset_path 'invitepeer16.png' %>) no-repeat center center;
|
|
||||||
}
|
|
||||||
.chat-box .participants .participant.pending .chat-participant-invite-call,
|
|
||||||
.chat-box .participants .participant.pending .chat-participant-invite-join {
|
|
||||||
background: #dab539 url(<%= asset_path 'ellipsis.gif' %>) no-repeat center center;
|
|
||||||
}
|
|
||||||
.chat-box .participants .participant .chat-participant-participating {
|
|
||||||
float: right;
|
|
||||||
display: none;
|
|
||||||
margin-top: 14px;
|
|
||||||
}
|
|
||||||
.chat-box .participants .participant .chat-participant-participating .green-dot {
|
|
||||||
background: #4fc059;
|
|
||||||
width: 12px;
|
|
||||||
height: 12px;
|
|
||||||
border-radius: 6px;
|
|
||||||
}
|
|
||||||
.chat-box .participants .participant.active .chat-participant-participating {
|
|
||||||
display: block;
|
|
||||||
}
|
|
||||||
.chat-box .chat-header {
|
|
||||||
width: 276px;
|
|
||||||
padding: 16px 8px 16px 16px;
|
|
||||||
font-size: 16px;
|
|
||||||
text-align: left;
|
|
||||||
font-weight: bold;
|
|
||||||
background-color: #000000;
|
|
||||||
color: #f5f5f5;
|
|
||||||
box-shadow: 0px 6px 3px rgba(0, 0, 0, 0.23);
|
|
||||||
}
|
|
||||||
.chat-box .chat-header .sound-toggle {
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
margin-right: 10px;
|
|
||||||
margin-top: -2px;
|
|
||||||
float: right;
|
|
||||||
background: url(<%= asset_path 'sound_sprite.png' %>) no-repeat;
|
|
||||||
}
|
|
||||||
.chat-box .chat-header .sound-toggle:hover {
|
|
||||||
background-position-x: -24px;
|
|
||||||
}
|
|
||||||
.chat-box .chat-header .sound-toggle.active {
|
|
||||||
background-position-y: -24px;
|
|
||||||
}
|
|
||||||
.chat-box .chat-input {
|
|
||||||
min-height: 80px;
|
|
||||||
width: 94%;
|
|
||||||
padding: 8px 3% 8px 3%;
|
|
||||||
font-size: 13px;
|
|
||||||
outline: none;
|
|
||||||
resize: none;
|
|
||||||
}
|
|
||||||
.chat-box .chat-messages {
|
|
||||||
width: 100%;
|
|
||||||
padding: 16px 0px 0px 0px;
|
|
||||||
overflow-y: auto;
|
|
||||||
flex-grow: 1;
|
|
||||||
}
|
|
||||||
.chat-box .chat-messages .chat-message {
|
|
||||||
width: 89%;
|
|
||||||
padding: 8px 8px 2px 8px;
|
|
||||||
color: #f5f5f5;
|
|
||||||
font-family: arial, sans-serif;
|
|
||||||
font-size: 13px;
|
|
||||||
line-height: 14px;
|
|
||||||
}
|
|
||||||
.chat-box .chat-messages .chat-message a:link {
|
|
||||||
color: #4fb5c0;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
.chat-box .chat-messages .chat-message a:visited {
|
|
||||||
color: #aea9fd;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
.chat-box .chat-messages .chat-message a:hover {
|
|
||||||
color: #dab539;
|
|
||||||
text-decoration: underline;
|
|
||||||
}
|
|
||||||
.chat-box .chat-messages .chat-message .chat-message-user {
|
|
||||||
width: 15%;
|
|
||||||
float: left;
|
|
||||||
overflow: hidden;
|
|
||||||
color: #BBB;
|
|
||||||
padding-top: 2px;
|
|
||||||
}
|
|
||||||
.chat-box .chat-messages .chat-message .chat-message-user img {
|
|
||||||
border: 2px solid #424242;
|
|
||||||
width: 32px;
|
|
||||||
height: 32px;
|
|
||||||
border-radius: 18px;
|
|
||||||
}
|
|
||||||
.chat-box .chat-messages .chat-message .chat-message-text {
|
|
||||||
width: 73%;
|
|
||||||
float: left;
|
|
||||||
margin-top: 12px;
|
|
||||||
padding: 2px 8px 0;
|
|
||||||
text-align: left;
|
|
||||||
word-wrap: break-word;
|
|
||||||
}
|
|
||||||
.chat-box .chat-messages .chat-message .chat-message-time {
|
|
||||||
float: right;
|
|
||||||
font-size: 10px;
|
|
||||||
color: #757575;
|
|
||||||
}
|
|
375
app/assets/stylesheets/junto.scss.erb
Normal file
375
app/assets/stylesheets/junto.scss.erb
Normal file
|
@ -0,0 +1,375 @@
|
||||||
|
.collaborator-video {
|
||||||
|
z-index: 1;
|
||||||
|
position: absolute;
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
cursor: default;
|
||||||
|
color: #FFF;
|
||||||
|
|
||||||
|
.video-receive {
|
||||||
|
position: absolute;
|
||||||
|
width: 160px;
|
||||||
|
padding: 20px 20px 20px 170px;
|
||||||
|
background: #424242;
|
||||||
|
height: 110px;
|
||||||
|
border-top-left-radius: 75px;
|
||||||
|
border-bottom-left-radius: 75px;
|
||||||
|
border-top-right-radius: 2px;
|
||||||
|
border-bottom-right-radius: 2px;
|
||||||
|
|
||||||
|
.video-statement {
|
||||||
|
margin-bottom: 10px;
|
||||||
|
}
|
||||||
|
.btn-group {
|
||||||
|
.btn-yes {
|
||||||
|
margin-right: 10px;
|
||||||
|
}
|
||||||
|
.btn-no {
|
||||||
|
background-color: #c04f4f;
|
||||||
|
&:hover {
|
||||||
|
background-color: #A54242;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.video-cutoff {
|
||||||
|
width: 150px;
|
||||||
|
height: 150px;
|
||||||
|
overflow: hidden;
|
||||||
|
border-radius: 75px;
|
||||||
|
z-index: 0;
|
||||||
|
position: relative;
|
||||||
|
-webkit-box-shadow: 0px 6px 3px rgba(0, 0, 0, 0.23), 10px 10px 10px rgba(0, 0, 0, 0.19);
|
||||||
|
-moz-box-shadow: 0px 6px 3px rgba(0, 0, 0, 0.23), 10px 10px 10px rgba(0, 0, 0, 0.19);
|
||||||
|
box-shadow: 0px 6px 3px rgba(0, 0, 0, 0.23), 10px 10px 10px rgba(0, 0, 0, 0.19);
|
||||||
|
|
||||||
|
video {
|
||||||
|
height: 150px;
|
||||||
|
margin-left: -25px;
|
||||||
|
}
|
||||||
|
.collaborator-video-avatar {
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
-webkit-user-select: none;
|
||||||
|
-khtml-user-select: none;
|
||||||
|
-moz-user-select: none;
|
||||||
|
-o-user-select: none;
|
||||||
|
user-select: none;
|
||||||
|
-webkit-user-drag: none;
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.video-audio {
|
||||||
|
position: absolute;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
top: 85%;
|
||||||
|
right: 0px;
|
||||||
|
cursor: pointer;
|
||||||
|
background: url(<%= asset_path 'audio_sprite.png' %>) no-repeat;
|
||||||
|
}
|
||||||
|
.video-audio:hover {
|
||||||
|
background-position-x: -24px;
|
||||||
|
}
|
||||||
|
.video-audio.active {
|
||||||
|
background-position-y: -24px;
|
||||||
|
}
|
||||||
|
.video-video {
|
||||||
|
position: absolute;
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
top: 85%;
|
||||||
|
left: 0px;
|
||||||
|
cursor: pointer;
|
||||||
|
background: url(<%= asset_path 'camera_sprite.png' %>) no-repeat;
|
||||||
|
}
|
||||||
|
.video-video:hover {
|
||||||
|
background-position-x: -24px;
|
||||||
|
}
|
||||||
|
.video-video.active {
|
||||||
|
background-position-y: -24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.collaborator-video.my-video {
|
||||||
|
left: 30px;
|
||||||
|
top: 72px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-box {
|
||||||
|
position: absolute;
|
||||||
|
right: 0;
|
||||||
|
z-index: 1;
|
||||||
|
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%;
|
||||||
|
left: -36px;
|
||||||
|
width: 36px;
|
||||||
|
height: 49px;
|
||||||
|
background: url(<%= asset_path 'junto.png' %>) no-repeat 2px 9px, url(<%= asset_path 'tray_tab.png' %>) no-repeat;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
&.active {
|
||||||
|
background: url(<%= asset_path 'junto_spinner_dark.gif' %>) no-repeat 2px 8px, url(<%= asset_path 'tray_tab.png' %>) no-repeat !important;
|
||||||
|
}
|
||||||
|
.chat-unread {
|
||||||
|
background: #DAB539;
|
||||||
|
position: absolute;
|
||||||
|
top: -3px;
|
||||||
|
left: -11px;
|
||||||
|
width: 20px;
|
||||||
|
height: 20px;
|
||||||
|
border-radius: 11px;
|
||||||
|
border: 2px solid #424242;
|
||||||
|
color: #424242;
|
||||||
|
text-align: center;
|
||||||
|
font-size: 12px;
|
||||||
|
font-weight: bold;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.junto-header {
|
||||||
|
width: 276px;
|
||||||
|
padding: 16px 8px 16px 16px;
|
||||||
|
font-size: 16px;
|
||||||
|
text-align: left;
|
||||||
|
font-weight: bold;
|
||||||
|
background-color: #000000;
|
||||||
|
color: #f5f5f5;
|
||||||
|
box-shadow: 0px 6px 3px rgba(0, 0, 0, 0.23);
|
||||||
|
|
||||||
|
.cursor-toggle {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
margin-right: 8px;
|
||||||
|
margin-top: -8px;
|
||||||
|
float: right;
|
||||||
|
background: url(<%= asset_path 'cursor_sprite.png' %>) no-repeat;
|
||||||
|
}
|
||||||
|
.cursor-toggle:hover {
|
||||||
|
background-position-x: -32px;
|
||||||
|
}
|
||||||
|
.cursor-toggle.active {
|
||||||
|
background-position-y: -32px;
|
||||||
|
}
|
||||||
|
.video-toggle {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-top: -8px;
|
||||||
|
float: right;
|
||||||
|
background: url(<%= asset_path 'video_sprite.png' %>) no-repeat;
|
||||||
|
}
|
||||||
|
.video-toggle:hover {
|
||||||
|
background-position-x: -32px;
|
||||||
|
}
|
||||||
|
.video-toggle.active {
|
||||||
|
background-position-y: -32px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.participants {
|
||||||
|
width: 100%;
|
||||||
|
min-height: 150px;
|
||||||
|
padding: 16px 0px 16px 0px;
|
||||||
|
text-align: left;
|
||||||
|
color: #f5f5f5;
|
||||||
|
overflow-y: auto;
|
||||||
|
|
||||||
|
.conversation-live {
|
||||||
|
padding: 5px 10px 5px 10px;
|
||||||
|
background: #c04f4f;
|
||||||
|
margin: 5px 10px;
|
||||||
|
border-radius: 2px;
|
||||||
|
}
|
||||||
|
.conversation-live .call-action {
|
||||||
|
float: right;
|
||||||
|
cursor: pointer;
|
||||||
|
color: #EBFF00;
|
||||||
|
}
|
||||||
|
.participant {
|
||||||
|
width: 89%;
|
||||||
|
padding: 8px 8px 2px 8px;
|
||||||
|
color: #f5f5f5;
|
||||||
|
font-family: arial, sans-serif;
|
||||||
|
font-size: 13px;
|
||||||
|
line-height: 14px;
|
||||||
|
|
||||||
|
.chat-participant-image {
|
||||||
|
width: 15%;
|
||||||
|
float: left;
|
||||||
|
overflow: hidden;
|
||||||
|
color: #BBB;
|
||||||
|
padding-top: 2px;
|
||||||
|
}
|
||||||
|
.chat-participant-image img {
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border-radius: 18px;
|
||||||
|
}
|
||||||
|
.chat-participant-name {
|
||||||
|
width: 53%;
|
||||||
|
float: left;
|
||||||
|
font-size: 13px;
|
||||||
|
font-weight: bold;
|
||||||
|
margin-top: 12px;
|
||||||
|
padding: 2px 8px 0;
|
||||||
|
text-align: left;
|
||||||
|
}
|
||||||
|
.chat-participant-invite-call,
|
||||||
|
.chat-participant-invite-join
|
||||||
|
{
|
||||||
|
float: right;
|
||||||
|
background: #4FC059 url(<%= asset_path 'invitepeer16.png' %>) no-repeat center center;
|
||||||
|
}
|
||||||
|
.chat-participant-invite-call.pending,
|
||||||
|
.chat-participant-invite-join.pending {
|
||||||
|
background: #dab539 url(<%= asset_path 'ellipsis.gif' %>) no-repeat center center;
|
||||||
|
}
|
||||||
|
.chat-participant-participating {
|
||||||
|
float: right;
|
||||||
|
margin-top: 14px;
|
||||||
|
}
|
||||||
|
.chat-participant-participating .green-dot {
|
||||||
|
background: #4fc059;
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border-radius: 6px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-header {
|
||||||
|
width: 276px;
|
||||||
|
padding: 16px 8px 16px 16px;
|
||||||
|
font-size: 16px;
|
||||||
|
text-align: left;
|
||||||
|
font-weight: bold;
|
||||||
|
background-color: #000000;
|
||||||
|
color: #f5f5f5;
|
||||||
|
box-shadow: 0px 6px 3px rgba(0, 0, 0, 0.23);
|
||||||
|
|
||||||
|
.sound-toggle {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
margin-right: 10px;
|
||||||
|
margin-top: -2px;
|
||||||
|
float: right;
|
||||||
|
background: url(<%= asset_path 'sound_sprite.png' %>) no-repeat;
|
||||||
|
}
|
||||||
|
.sound-toggle:hover {
|
||||||
|
background-position-x: -24px;
|
||||||
|
}
|
||||||
|
.sound-toggle.active {
|
||||||
|
background-position-y: -24px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$chat_font_size: 16px;
|
||||||
|
|
||||||
|
.chat-input {
|
||||||
|
min-height: 80px;
|
||||||
|
width: 88%;
|
||||||
|
padding: 8px 9% 8px 3%;
|
||||||
|
font-size: $chat_font_size;
|
||||||
|
outline: none;
|
||||||
|
resize: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.chat-messages {
|
||||||
|
width: 100%;
|
||||||
|
padding: 16px 0px;
|
||||||
|
overflow-y: auto;
|
||||||
|
flex-grow: 1;
|
||||||
|
|
||||||
|
.chat-message {
|
||||||
|
width: 89%;
|
||||||
|
padding: 8px 8px 2px 8px;
|
||||||
|
color: #f5f5f5;
|
||||||
|
font-family: arial, sans-serif;
|
||||||
|
font-size: $chat_font_size;
|
||||||
|
line-height: $chat_font_size + 1px;
|
||||||
|
|
||||||
|
a:link {
|
||||||
|
color: #4fb5c0;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
a:visited {
|
||||||
|
color: #aea9fd;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
a:hover {
|
||||||
|
color: #dab539;
|
||||||
|
text-decoration: underline;
|
||||||
|
}
|
||||||
|
.chat-message-user {
|
||||||
|
width: 12%;
|
||||||
|
float: left;
|
||||||
|
overflow: hidden;
|
||||||
|
color: #BBB;
|
||||||
|
padding-top: 2px;
|
||||||
|
}
|
||||||
|
.chat-message-user img {
|
||||||
|
border: 2px solid #424242;
|
||||||
|
width: 28px;
|
||||||
|
height: 28px;
|
||||||
|
border-radius: 16px;
|
||||||
|
}
|
||||||
|
.chat-message-meta {
|
||||||
|
padding: 0 8px;
|
||||||
|
float: left;
|
||||||
|
}
|
||||||
|
.chat-message-username {
|
||||||
|
color: #4fc059;
|
||||||
|
}
|
||||||
|
.chat-message-text {
|
||||||
|
width: 80%;
|
||||||
|
float: left;
|
||||||
|
padding: 2px 8px 0;
|
||||||
|
text-align: left;
|
||||||
|
word-wrap: break-word;
|
||||||
|
}
|
||||||
|
.chat-message-time {
|
||||||
|
font-size: 12px;
|
||||||
|
color: #757575;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.new-message-area {
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
.emoji-mart {
|
||||||
|
position: absolute;
|
||||||
|
bottom: 98px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.extra-message-options {
|
||||||
|
height: 20px;
|
||||||
|
position: absolute;
|
||||||
|
right: 2px;
|
||||||
|
bottom: 74px;
|
||||||
|
|
||||||
|
.emoji-picker-button {
|
||||||
|
font-size: 16px;
|
||||||
|
line-height: 20px;
|
||||||
|
cursor: pointer;
|
||||||
|
padding: 4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
288
app/assets/stylesheets/mapcard.scss.erb
Normal file
288
app/assets/stylesheets/mapcard.scss.erb
Normal file
|
@ -0,0 +1,288 @@
|
||||||
|
/* Map Cards */
|
||||||
|
|
||||||
|
.map {
|
||||||
|
display:inline-block;
|
||||||
|
width:220px;
|
||||||
|
height:340px;
|
||||||
|
font-size: 12px;
|
||||||
|
text-align: left;
|
||||||
|
overflow: visible;
|
||||||
|
background: #e8e8e8;
|
||||||
|
border-radius:2px;
|
||||||
|
margin:16px;
|
||||||
|
box-shadow: 0px 3px 3px rgba(0,0,0,0.23), 0 3px 3px rgba(0,0,0,0.16);
|
||||||
|
|
||||||
|
&.newMap {
|
||||||
|
float: left;
|
||||||
|
position: relative;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background: #dcdcdc;
|
||||||
|
|
||||||
|
.newMapImage {
|
||||||
|
background-position: 0 -72px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
a {
|
||||||
|
height: 340px;
|
||||||
|
display: block;
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
|
||||||
|
.newMapImage {
|
||||||
|
display: block;
|
||||||
|
width: 72px;
|
||||||
|
height: 72px;
|
||||||
|
background-image: url("<%= asset_data_uri('newmap_sprite.png') %>");
|
||||||
|
background-repeat: no-repeat;
|
||||||
|
background-position: 0 0;
|
||||||
|
position: absolute;
|
||||||
|
left: 50%;
|
||||||
|
margin-left: -36px;
|
||||||
|
top: 50%;
|
||||||
|
margin-top: -36px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span {
|
||||||
|
font-family: 'din-regular', sans-serif;
|
||||||
|
font-size: 18px;
|
||||||
|
line-height: 22px;
|
||||||
|
text-align: center;
|
||||||
|
display: block;
|
||||||
|
padding-top: 220px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mapCard {
|
||||||
|
position:relative;
|
||||||
|
width:100%;
|
||||||
|
height:308px;
|
||||||
|
padding: 0 0 16px 0;
|
||||||
|
color: #424242;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
.dropdownMenu .menuToggle .circle {
|
||||||
|
background-color: #FFF;
|
||||||
|
}
|
||||||
|
.dropdownMenu .menuToggle:hover .circle {
|
||||||
|
background-color: #DDD;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mainContent {
|
||||||
|
filter: blur(2px);
|
||||||
|
}
|
||||||
|
|
||||||
|
.mapMetadata {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mapHasMapper, .mapHasConversation {
|
||||||
|
position: absolute;
|
||||||
|
top: 8px;
|
||||||
|
left: 8px;
|
||||||
|
min-width: 32px;
|
||||||
|
min-height: 32px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #FFF;
|
||||||
|
border-radius: 2px;
|
||||||
|
|
||||||
|
.mapperList {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mapperList {
|
||||||
|
display: none;
|
||||||
|
padding: 8px;
|
||||||
|
list-style-type: none;
|
||||||
|
|
||||||
|
li {
|
||||||
|
&.live {
|
||||||
|
height: 32px;
|
||||||
|
padding-left: 32px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 12px;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
padding-left: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mapHasMapper {
|
||||||
|
background: url('<%= asset_path('junto.png') %>') no-repeat 4px 0;
|
||||||
|
}
|
||||||
|
.mapHasConversation {
|
||||||
|
background: url('<%= asset_path('junto.gif') %>') no-repeat 4px 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.dropdownMenu {
|
||||||
|
position: absolute;
|
||||||
|
top: 8px;
|
||||||
|
right: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
|
||||||
|
.menuToggle {
|
||||||
|
width: 30px;
|
||||||
|
height: 10px;
|
||||||
|
|
||||||
|
.circle {
|
||||||
|
display: inline-block;
|
||||||
|
background-color: #454545;
|
||||||
|
width: 6px;
|
||||||
|
height: 6px;
|
||||||
|
border-radius: 3px;
|
||||||
|
margin: 2px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&:hover .circle {
|
||||||
|
background-color: #222;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.menuItems {
|
||||||
|
position: absolute;
|
||||||
|
top: 18px;
|
||||||
|
right: 0px;
|
||||||
|
background: #FFF;
|
||||||
|
border-radius: 2px;
|
||||||
|
list-style-type: none;
|
||||||
|
color: #454545;
|
||||||
|
|
||||||
|
li {
|
||||||
|
white-space: nowrap;
|
||||||
|
padding: 6px;
|
||||||
|
|
||||||
|
&:hover {
|
||||||
|
background-color: #DDD;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.mapScreenshot {
|
||||||
|
width: 100%;
|
||||||
|
height: 220px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.mapScreenshot img {
|
||||||
|
width: 100%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.title {
|
||||||
|
word-wrap: break-word;
|
||||||
|
font-size:18px;
|
||||||
|
line-height:22px;
|
||||||
|
height: 71px;
|
||||||
|
display:table;
|
||||||
|
padding: 0 16px;
|
||||||
|
font-family: 'din-regular', sans-serif;
|
||||||
|
margin: 0 auto;
|
||||||
|
|
||||||
|
.innerTitle {
|
||||||
|
display: table-cell;
|
||||||
|
vertical-align: middle;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.creatorAndPerm {
|
||||||
|
padding: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.creatorImage {
|
||||||
|
display: inline-block;
|
||||||
|
border-radius: 16px;
|
||||||
|
vertical-align: middle;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
}
|
||||||
|
|
||||||
|
span.creatorName {
|
||||||
|
margin-left: 8px;
|
||||||
|
max-width: 162px;
|
||||||
|
display: inline-block;
|
||||||
|
overflow: hidden;
|
||||||
|
white-space: nowrap;
|
||||||
|
text-overflow: ellipsis;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.creatorAndPerm.cardHasViewOnly span.creatorName {
|
||||||
|
max-width: 95px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.cardViewOnly {
|
||||||
|
float: right;
|
||||||
|
line-height: 32px;
|
||||||
|
padding-right: 10px;
|
||||||
|
color: #454545;
|
||||||
|
}
|
||||||
|
|
||||||
|
.scroll {
|
||||||
|
display:block;
|
||||||
|
font-family: helvetica, sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
word-wrap: break-word;
|
||||||
|
text-align: center;
|
||||||
|
margin-top: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.mapMetadata {
|
||||||
|
display: none;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
left: 0;
|
||||||
|
padding: 40px 20px 0;
|
||||||
|
height: 300px;
|
||||||
|
font-family: 'din-regular', sans-serif;
|
||||||
|
font-size: 12px;
|
||||||
|
color: #FFF;
|
||||||
|
background: -moz-linear-gradient(top, rgba(0,0,0,0.65) 0%, rgba(0,0,0,0.43) 81%, rgba(0,0,0,0) 100%);
|
||||||
|
background: -webkit-linear-gradient(top, rgba(0,0,0,0.65) 0%,rgba(0,0,0,0.43) 81%,rgba(0,0,0,0) 100%);
|
||||||
|
background: linear-gradient(to bottom, rgba(0,0,0,0.65) 0%,rgba(0,0,0,0.43) 81%,rgba(0,0,0,0) 100%);
|
||||||
|
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#a6000000', endColorstr='#00000000',GradientType=0 );
|
||||||
|
}
|
||||||
|
|
||||||
|
.metadataSection {
|
||||||
|
padding: 16px 0;
|
||||||
|
width: 90px;
|
||||||
|
float: left;
|
||||||
|
font-family: 'din-medium', sans-serif;
|
||||||
|
text-align: center;
|
||||||
|
|
||||||
|
div {
|
||||||
|
background: url('<%= asset_path('metadata.png') %>') no-repeat;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.numTopicsIcon {
|
||||||
|
background-position: 0 -32px;
|
||||||
|
}
|
||||||
|
.numStarsIcon {
|
||||||
|
background-position: 0 0;
|
||||||
|
}
|
||||||
|
.numSynapsesIcon {
|
||||||
|
background-position: -32px -32px;
|
||||||
|
}
|
||||||
|
.numContributorsIcon {
|
||||||
|
background-position: -32px 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,15 +1,50 @@
|
||||||
#mobile_header {
|
@media only screen and (max-width : 752px) and (min-width : 504px) {
|
||||||
display: none;
|
.sidebarSearch .tt-hint, .sidebarSearch .sidebarSearchField {
|
||||||
|
width: 160px !important;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Smartphones (portrait and landscape) ----------- */
|
/* when this switches to two lines */
|
||||||
@media only screen and (max-device-width : 480px) {
|
@media only screen and (max-width : 728px) {
|
||||||
.upperLeftUI, .upperRightUI, .openCheatsheet, .mapInfoIcon, .uv-icon, .chat-box, #exploreMapsHeader {
|
.controller-notifications .notificationsPage .notification .notification-read-unread a {
|
||||||
|
margin-top: -20px !important;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media only screen and (max-width : 390px) {
|
||||||
|
.map .mapCard .mobileMetadata {
|
||||||
|
width: 190px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@media only screen and (min-width : 390px) {
|
||||||
|
.map .mapCard .mobileMetadata {
|
||||||
|
width: 390px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* 800 is the max-width for centerContent */
|
||||||
|
@media only screen and (max-width : 800px) {
|
||||||
|
.centerContent.withPadding {
|
||||||
|
margin-top: 0;
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* Smartphones (portrait and landscape) ----------- the minimum space that two map cards can fit side by side */
|
||||||
|
@media only screen and (max-width : 504px) {
|
||||||
|
.upperLeftUI, .upperRightUI, .openCheatsheet, .mapInfoIcon, .feedback-icon, .chat-box, #navBar {
|
||||||
display: none !important;
|
display: none !important;
|
||||||
}
|
}
|
||||||
|
|
||||||
#mobile_header {
|
.notificationsPage .page-header {
|
||||||
display: block;
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
.controller-notifications .notificationsPage .notification .notification-read-unread {
|
||||||
|
display: block !important;
|
||||||
|
}
|
||||||
|
.controller-notifications .notificationsPage .notification .notification-date {
|
||||||
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.homeWrapper {
|
.homeWrapper {
|
||||||
|
@ -29,7 +64,7 @@
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
.homeVideo {
|
.homeVideo {
|
||||||
width: 100%;
|
width: 100% !important;
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
}
|
||||||
.fullWidthWrapper.withPartners {
|
.fullWidthWrapper.withPartners {
|
||||||
|
@ -40,7 +75,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
#yield {
|
#yield {
|
||||||
height: 100%;
|
padding-top: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.new_session, .new_user, .edit_user, .login, .forgotPassword {
|
.new_session, .new_user, .edit_user, .login, .forgotPassword {
|
||||||
|
@ -49,7 +84,7 @@
|
||||||
left: auto;
|
left: auto;
|
||||||
width: 78%;
|
width: 78%;
|
||||||
padding: 16px 10%;
|
padding: 16px 10%;
|
||||||
margin: 50px auto 0 auto;
|
margin: 0 auto;
|
||||||
}
|
}
|
||||||
|
|
||||||
.centerGreyForm input[type="text"], .centerGreyForm input[type="email"], .centerGreyForm input[type="password"] {
|
.centerGreyForm input[type="text"], .centerGreyForm input[type="email"], .centerGreyForm input[type="password"] {
|
||||||
|
@ -65,15 +100,28 @@
|
||||||
max-width: 360px;
|
max-width: 360px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#wrapper .requestInvite {
|
.requestInviteHeader {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
.requestInvite {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
padding: 0;
|
height: calc(100% - 50px);
|
||||||
|
z-index: 1;
|
||||||
|
position: relative;
|
||||||
|
left: 0;
|
||||||
|
margin-left: 0px;
|
||||||
|
margin-top: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#exploreMaps > div {
|
#exploreMaps > div {
|
||||||
margin-top: 70px;
|
margin-top: 70px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.mapper {
|
||||||
|
width: 100%;
|
||||||
|
margin: 0 0 30px 0;
|
||||||
|
}
|
||||||
|
|
||||||
.map.newMap {
|
.map.newMap {
|
||||||
a {
|
a {
|
||||||
height: auto;
|
height: auto;
|
||||||
|
@ -100,29 +148,67 @@
|
||||||
.map.newMap:hover .newMapImage {
|
.map.newMap:hover .newMapImage {
|
||||||
background-position: 0 -40px;
|
background-position: 0 -40px;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
/* Smartphones (portrait) ----------- */
|
|
||||||
@media only screen and (max-width : 400px) {
|
|
||||||
|
|
||||||
.map {
|
.map {
|
||||||
width: 100%;
|
width: 100%;
|
||||||
margin: 0 0 30px 0;
|
margin: 0 0 30px 0;
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
|
||||||
|
|
||||||
.mapCard {
|
.mapCard {
|
||||||
height: auto;
|
height: auto;
|
||||||
}
|
padding: 0;
|
||||||
|
|
||||||
.mapCard .title {
|
&:hover {
|
||||||
text-align: left;
|
.mainContent {
|
||||||
}
|
filter: none;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mobileHasMapper, .mobileHasConversation {
|
||||||
|
.mapperList {
|
||||||
|
padding: 8px 16px;
|
||||||
|
list-style-type: none;
|
||||||
|
|
||||||
.mapCard .mapScreenshot {
|
li {
|
||||||
display: none;
|
&.live {
|
||||||
}
|
height: 32px;
|
||||||
|
padding-left: 32px;
|
||||||
|
font-size: 16px;
|
||||||
|
}
|
||||||
|
|
||||||
|
img {
|
||||||
|
width: 24px;
|
||||||
|
height: 24px;
|
||||||
|
border-radius: 12px;
|
||||||
|
display: inline-block;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
span {
|
||||||
|
padding-left: 10px;
|
||||||
|
font-size: 14px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
.mobileHasMapper {
|
||||||
|
background: url('<%= asset_path('junto.png') %>') no-repeat 12px 0;
|
||||||
|
}
|
||||||
|
.mobileHasConversation {
|
||||||
|
background: url('<%= asset_path('junto.gif') %>') no-repeat 12px 0;
|
||||||
|
}
|
||||||
|
.mobileMetadata {
|
||||||
|
margin: 0 auto;
|
||||||
|
}
|
||||||
|
.title {
|
||||||
|
text-align: left;
|
||||||
|
display: block;
|
||||||
|
height: auto;
|
||||||
|
padding: 16px;
|
||||||
|
}
|
||||||
|
.desc {
|
||||||
|
padding: 0 16px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#mobile_header {
|
#mobile_header {
|
||||||
|
@ -131,6 +217,7 @@
|
||||||
width: 100%;
|
width: 100%;
|
||||||
box-shadow: 0px 3px 3px rgba(0,0,0,0.23), 0 3px 3px rgba(0,0,0,0.16);
|
box-shadow: 0px 3px 3px rgba(0,0,0,0.23), 0 3px 3px rgba(0,0,0,0.16);
|
||||||
position: fixed;
|
position: fixed;
|
||||||
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#menu_icon {
|
#menu_icon {
|
||||||
|
@ -153,8 +240,16 @@
|
||||||
line-height: 50px;
|
line-height: 50px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#mobile_header #menu_icon .unread-notifications-dot {
|
||||||
|
top: 5px;
|
||||||
|
left: 29px;
|
||||||
|
width: 12px;
|
||||||
|
height: 12px;
|
||||||
|
border: 3px solid #eee;
|
||||||
|
border-radius: 9px;
|
||||||
|
}
|
||||||
|
|
||||||
#mobile_menu {
|
#mobile_menu {
|
||||||
display: none;
|
|
||||||
background: #EEE;
|
background: #EEE;
|
||||||
position: fixed;
|
position: fixed;
|
||||||
top: 50px;
|
top: 50px;
|
||||||
|
@ -162,11 +257,30 @@
|
||||||
padding: 10px;
|
padding: 10px;
|
||||||
width: 200px;
|
width: 200px;
|
||||||
box-shadow: 3px 3px 3px rgba(0,0,0,0.23), 3px 3px 3px rgba(0,0,0,0.16);
|
box-shadow: 3px 3px 3px rgba(0,0,0,0.23), 3px 3px 3px rgba(0,0,0,0.16);
|
||||||
}
|
z-index: 2;
|
||||||
|
|
||||||
#mobile_menu li {
|
li {
|
||||||
padding: 10px;
|
padding: 7px 10px;
|
||||||
list-style: none;
|
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;
|
||||||
|
|
||||||
|
.unread-notifications-dot {
|
||||||
|
top: 50%;
|
||||||
|
left: 0px;
|
||||||
|
margin-top: -4px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
li.mobileMenuUser {
|
li.mobileMenuUser {
|
||||||
|
|
237
app/assets/stylesheets/notifications.scss.erb
Normal file
237
app/assets/stylesheets/notifications.scss.erb
Normal file
|
@ -0,0 +1,237 @@
|
||||||
|
$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;
|
||||||
|
background-color: #e22;
|
||||||
|
border-radius: $unread_notifications_dot_size / 2;
|
||||||
|
position: absolute;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.upperRightUI {
|
||||||
|
.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 {
|
||||||
|
.notificationPage,
|
||||||
|
.notificationsPage {
|
||||||
|
font-family: 'din-regular', Sans-Serif;
|
||||||
|
|
||||||
|
& a:hover {
|
||||||
|
text-decoration: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
& > .notification-title {
|
||||||
|
border-bottom: 1px solid #eee;
|
||||||
|
padding-bottom: 0.25em;
|
||||||
|
margin-bottom: 0.5em;
|
||||||
|
}
|
||||||
|
|
||||||
|
.back {
|
||||||
|
margin-top: 1em;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.notificationsPage {
|
||||||
|
header {
|
||||||
|
margin-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.emptyInbox {
|
||||||
|
padding-top: 15px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
.notificationPage {
|
||||||
|
.thirty-two-avatar {
|
||||||
|
display: inline-block;
|
||||||
|
width: 32px;
|
||||||
|
height: 32px;
|
||||||
|
border-radius: 16px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
|
||||||
|
.button {
|
||||||
|
line-height: 32px;
|
||||||
|
|
||||||
|
img {
|
||||||
|
margin-top: 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
&.decline {
|
||||||
|
background: #DB5D5D;
|
||||||
|
&:hover {
|
||||||
|
background: #DC4B4B;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.notification-body {
|
||||||
|
p, div {
|
||||||
|
margin: 1em auto;
|
||||||
|
line-height: 20px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
87
app/assets/stylesheets/request_access.scss.erb
Normal file
87
app/assets/stylesheets/request_access.scss.erb
Normal file
|
@ -0,0 +1,87 @@
|
||||||
|
.viewOnly {
|
||||||
|
float: left;
|
||||||
|
margin-left: 16px;
|
||||||
|
height: 32px;
|
||||||
|
border: 1px solid #BDBDBD;
|
||||||
|
border-radius: 2px;
|
||||||
|
background-color: #424242;
|
||||||
|
color: #FFF;
|
||||||
|
font-size: 14px;
|
||||||
|
line-height: 32px;
|
||||||
|
|
||||||
|
&.isViewOnly {
|
||||||
|
display: block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.eyeball {
|
||||||
|
background: url('<%= asset_path('view-only.png') %>') no-repeat 4px 0;
|
||||||
|
padding-left: 40px;
|
||||||
|
border-right: #747474;
|
||||||
|
padding-right: 10px;
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.requestNotice {
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 8px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.requestAccess {
|
||||||
|
background-color: #a354cd;
|
||||||
|
&:hover {
|
||||||
|
background-color: #9150bc;
|
||||||
|
}
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.requestPending {
|
||||||
|
background-color: #4fc059;
|
||||||
|
}
|
||||||
|
|
||||||
|
.requestNotAccepted {
|
||||||
|
background-color: #c04f4f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
.request_access {
|
||||||
|
position: absolute;
|
||||||
|
width: 90%;
|
||||||
|
margin: 0 5%;
|
||||||
|
|
||||||
|
.monkey {
|
||||||
|
width: 250px;
|
||||||
|
height: 250px;
|
||||||
|
border: 6px solid #424242;
|
||||||
|
border-radius: 125px;
|
||||||
|
background: url(https://s3.amazonaws.com/metamaps-assets/site/monkeyselfie.jpg) no-repeat;
|
||||||
|
background-position: 50% 20%;
|
||||||
|
background-size: 100%;
|
||||||
|
margin: 80px auto 20px auto;
|
||||||
|
}
|
||||||
|
|
||||||
|
.explainer_text {
|
||||||
|
padding: 0 20% 0 20%;
|
||||||
|
font-size: 24px;
|
||||||
|
line-height: 30px;
|
||||||
|
margin-bottom: 20px;
|
||||||
|
text-align: center;
|
||||||
|
}
|
||||||
|
|
||||||
|
.make_request {
|
||||||
|
background-color: #a354cd;
|
||||||
|
display: block;
|
||||||
|
width: 220px;
|
||||||
|
height: 14px;
|
||||||
|
padding: 16px 0;
|
||||||
|
margin-bottom: 16px;
|
||||||
|
text-align: center;
|
||||||
|
border-radius: 2px;
|
||||||
|
font-size: 14px;
|
||||||
|
box-shadow: 0px 1px 1.5px rgba(0,0,0,0.12), 0 1px 1px rgba(0,0,0,0.24);
|
||||||
|
margin: 0 auto 20px auto;
|
||||||
|
text-decoration: none;
|
||||||
|
color: #FFFFFF !important;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -93,7 +93,7 @@
|
||||||
|
|
||||||
.sidebarSearchField {
|
.sidebarSearchField {
|
||||||
float: left;
|
float: left;
|
||||||
width: 380px;
|
width: 379px;
|
||||||
padding: 7px 10px 3px 10px;
|
padding: 7px 10px 3px 10px;
|
||||||
height: 20px;
|
height: 20px;
|
||||||
border-top: 1px solid #BDBDBD;
|
border-top: 1px solid #BDBDBD;
|
||||||
|
|
6
app/channels/application_cable/channel.rb
Normal file
6
app/channels/application_cable/channel.rb
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module ApplicationCable
|
||||||
|
class Channel < ActionCable::Channel::Base
|
||||||
|
end
|
||||||
|
end
|
23
app/channels/application_cable/connection.rb
Normal file
23
app/channels/application_cable/connection.rb
Normal file
|
@ -0,0 +1,23 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module ApplicationCable
|
||||||
|
class Connection < ActionCable::Connection::Base
|
||||||
|
identified_by :current_user
|
||||||
|
|
||||||
|
def connect
|
||||||
|
self.current_user = find_verified_user
|
||||||
|
logger.add_tags 'ActionCable', current_user.name
|
||||||
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def find_verified_user
|
||||||
|
verified_user = User.find_by(id: cookies.signed['user.id'])
|
||||||
|
if verified_user && cookies.signed['user.expires_at'] > Time.now.getlocal
|
||||||
|
verified_user
|
||||||
|
else
|
||||||
|
reject_unauthorized_connection
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
18
app/channels/map_channel.rb
Normal file
18
app/channels/map_channel.rb
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class MapChannel < ApplicationCable::Channel
|
||||||
|
# Called when the consumer has successfully
|
||||||
|
# become a subscriber of this channel.
|
||||||
|
def subscribed
|
||||||
|
map = Map.find(params[:id])
|
||||||
|
return unless Pundit.policy(current_user, map).show?
|
||||||
|
stream_from "map_#{params[:id]}"
|
||||||
|
Events::UserPresentOnMap.publish!(map, current_user)
|
||||||
|
end
|
||||||
|
|
||||||
|
def unsubscribed
|
||||||
|
map = Map.find(params[:id])
|
||||||
|
return unless Pundit.policy(current_user, map).show?
|
||||||
|
Events::UserNotPresentOnMap.publish!(map, current_user)
|
||||||
|
end
|
||||||
|
end
|
90
app/controllers/access_controller.rb
Normal file
90
app/controllers/access_controller.rb
Normal file
|
@ -0,0 +1,90 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class AccessController < ApplicationController
|
||||||
|
before_action :require_user, only: %i[access access_request
|
||||||
|
approve_access approve_access_post
|
||||||
|
deny_access deny_access_post request_access]
|
||||||
|
before_action :set_map, only: %i[access access_request
|
||||||
|
approve_access approve_access_post
|
||||||
|
deny_access deny_access_post request_access]
|
||||||
|
after_action :verify_authorized
|
||||||
|
|
||||||
|
# GET maps/:id/request_access
|
||||||
|
def request_access
|
||||||
|
@map = nil
|
||||||
|
respond_to do |format|
|
||||||
|
format.html do
|
||||||
|
render 'maps/request_access'
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# POST maps/:id/access_request
|
||||||
|
def access_request
|
||||||
|
AccessRequest.create(user: current_user, map: @map)
|
||||||
|
respond_to do |format|
|
||||||
|
format.json { head :ok }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# POST maps/:id/access
|
||||||
|
def access
|
||||||
|
user_ids = params[:access].to_a.map(&:to_i) || []
|
||||||
|
|
||||||
|
@map.add_new_collaborators(user_ids)
|
||||||
|
@map.remove_old_collaborators(user_ids)
|
||||||
|
|
||||||
|
respond_to do |format|
|
||||||
|
format.json { head :ok }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# GET maps/:id/approve_access/:request_id
|
||||||
|
def approve_access
|
||||||
|
request = AccessRequest.find(params[:request_id])
|
||||||
|
request.approve # also marks mailboxer notification as read
|
||||||
|
respond_to do |format|
|
||||||
|
format.html { redirect_to map_path(@map), notice: 'Request was approved' }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# GET maps/:id/deny_access/:request_id
|
||||||
|
def deny_access
|
||||||
|
request = AccessRequest.find(params[:request_id])
|
||||||
|
request.deny # also marks mailboxer notification as read
|
||||||
|
respond_to do |format|
|
||||||
|
format.html { redirect_to map_path(@map), notice: 'Request was turned down' }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# POST maps/:id/approve_access/:request_id
|
||||||
|
def approve_access_post
|
||||||
|
request = AccessRequest.find(params[:request_id])
|
||||||
|
request.approve
|
||||||
|
respond_to do |format|
|
||||||
|
format.js
|
||||||
|
format.json do
|
||||||
|
head :ok
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# POST maps/:id/deny_access/:request_id
|
||||||
|
def deny_access_post
|
||||||
|
request = AccessRequest.find(params[:request_id])
|
||||||
|
request.deny
|
||||||
|
respond_to do |format|
|
||||||
|
format.js
|
||||||
|
format.json do
|
||||||
|
head :ok
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def set_map
|
||||||
|
@map = Map.find(params[:id])
|
||||||
|
authorize @map
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,4 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Api
|
module Api
|
||||||
module V1
|
module V1
|
||||||
class DeprecatedController < ApplicationController
|
class DeprecatedController < ApplicationController
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Api
|
module Api
|
||||||
module V2
|
module V2
|
||||||
class MappingsController < RestfulController
|
class MappingsController < WithUpdatesController
|
||||||
def searchable_columns
|
def searchable_columns
|
||||||
[]
|
[]
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,15 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Api
|
module Api
|
||||||
module V2
|
module V2
|
||||||
class MapsController < RestfulController
|
class MapsController < WithUpdatesController
|
||||||
def searchable_columns
|
def searchable_columns
|
||||||
[:name, :desc]
|
%i[name desc]
|
||||||
|
end
|
||||||
|
|
||||||
|
def apply_filters(collection)
|
||||||
|
collection = collection.where(user_id: params[:user_id]) if params[:user_id]
|
||||||
|
collection
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Api
|
module Api
|
||||||
module V2
|
module V2
|
||||||
class MetacodesController < RestfulController
|
class MetacodesController < RestfulController
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Api
|
module Api
|
||||||
module V2
|
module V2
|
||||||
class RestfulController < ActionController::Base
|
class RestfulController < ActionController::Base
|
||||||
|
@ -7,7 +8,7 @@ module Api
|
||||||
|
|
||||||
snorlax_used_rest!
|
snorlax_used_rest!
|
||||||
|
|
||||||
before_action :load_resource, only: [:show, :update, :destroy]
|
before_action :load_resource, only: %i[show update destroy]
|
||||||
after_action :verify_authorized
|
after_action :verify_authorized
|
||||||
|
|
||||||
def index
|
def index
|
||||||
|
@ -45,7 +46,7 @@ module Api
|
||||||
end
|
end
|
||||||
|
|
||||||
def current_user
|
def current_user
|
||||||
super || token_user || doorkeeper_user || nil
|
token_user || doorkeeper_user
|
||||||
end
|
end
|
||||||
|
|
||||||
def load_resource
|
def load_resource
|
||||||
|
@ -86,12 +87,12 @@ module Api
|
||||||
|
|
||||||
def token_user
|
def token_user
|
||||||
token = params[:access_token]
|
token = params[:access_token]
|
||||||
access_token = Token.find_by_token(token)
|
access_token = Token.find_by(token: token)
|
||||||
@token_user ||= access_token.user if access_token
|
@token_user ||= access_token.user if access_token
|
||||||
end
|
end
|
||||||
|
|
||||||
def doorkeeper_user
|
def doorkeeper_user
|
||||||
return unless doorkeeper_token.present?
|
return if doorkeeper_token.blank?
|
||||||
doorkeeper_render_error unless valid_doorkeeper_token?
|
doorkeeper_render_error unless valid_doorkeeper_token?
|
||||||
@doorkeeper_user ||= User.find(doorkeeper_token.resource_owner_id)
|
@doorkeeper_user ||= User.find(doorkeeper_token.resource_owner_id)
|
||||||
end
|
end
|
||||||
|
@ -141,6 +142,7 @@ module Api
|
||||||
collection = accessible_records
|
collection = accessible_records
|
||||||
collection = yield collection if block_given?
|
collection = yield collection if block_given?
|
||||||
collection = search_by_q(collection) if params[:q]
|
collection = search_by_q(collection) if params[:q]
|
||||||
|
collection = apply_filters(collection)
|
||||||
collection = order_by_sort(collection) if params[:sort]
|
collection = order_by_sort(collection) if params[:sort]
|
||||||
collection = collection.page(params[:page]).per(params[:per])
|
collection = collection.page(params[:page]).per(params[:per])
|
||||||
self.collection = collection
|
self.collection = collection
|
||||||
|
@ -148,25 +150,41 @@ module Api
|
||||||
|
|
||||||
# override this method to explicitly set searchable columns
|
# override this method to explicitly set searchable columns
|
||||||
def searchable_columns
|
def searchable_columns
|
||||||
|
return @searchable_columns unless @searchable_columns.nil?
|
||||||
|
|
||||||
columns = resource_class.columns.select do |column|
|
columns = resource_class.columns.select do |column|
|
||||||
column.type == :text || column.type == :string
|
column.type == :text || column.type == :string
|
||||||
end
|
end
|
||||||
columns.map(&:name)
|
@searchable_columns = columns.map(&:name)
|
||||||
|
end
|
||||||
|
|
||||||
|
# e.g. ?q=test&searchfields=name,desc
|
||||||
|
def searchfields
|
||||||
|
return searchable_columns if params[:searchfields].blank?
|
||||||
|
|
||||||
|
searchfields = params[:searchfields].split(',')
|
||||||
|
searchfields.select! { |f| searchable_columns.include?(f.to_sym) }
|
||||||
|
searchfields.empty? ? searchable_columns : searchfields
|
||||||
end
|
end
|
||||||
|
|
||||||
# thanks to http://stackoverflow.com/questions/4430578
|
# thanks to http://stackoverflow.com/questions/4430578
|
||||||
def search_by_q(collection)
|
def search_by_q(collection)
|
||||||
table = resource_class.arel_table
|
table = resource_class.arel_table
|
||||||
safe_query = "%#{params[:q].gsub(/[%_]/, '\\\\\0')}%"
|
safe_query = "%#{params[:q].gsub(/[%_]/, '\\\\\0')}%"
|
||||||
search_column = -> (column) { table[column].matches(safe_query) }
|
search_column = ->(column) { table[column].matches(safe_query) }
|
||||||
|
|
||||||
condition = searchable_columns.reduce(nil) do |prev, column|
|
condition = searchfields.reduce(nil) do |prev, column|
|
||||||
next search_column.call(column) if prev.nil?
|
next search_column.call(column) if prev.nil?
|
||||||
search_column.call(column).or(prev)
|
search_column.call(column).or(prev)
|
||||||
end
|
end
|
||||||
collection.where(condition)
|
collection.where(condition)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def apply_filters(collection)
|
||||||
|
# override this function for specific filters
|
||||||
|
collection
|
||||||
|
end
|
||||||
|
|
||||||
def order_by_sort(collection)
|
def order_by_sort(collection)
|
||||||
builder = collection
|
builder = collection
|
||||||
sorts = params[:sort].split(',')
|
sorts = params[:sort].split(',')
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Api
|
module Api
|
||||||
module V2
|
module V2
|
||||||
class SessionsController < ApplicationController
|
class SessionsController < ApplicationController
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Api
|
module Api
|
||||||
module V2
|
module V2
|
||||||
class StarsController < RestfulController
|
class StarsController < RestfulController
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Api
|
module Api
|
||||||
module V2
|
module V2
|
||||||
class SynapsesController < RestfulController
|
class SynapsesController < WithUpdatesController
|
||||||
def searchable_columns
|
def searchable_columns
|
||||||
[:desc]
|
[:desc]
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,7 +1,10 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Api
|
module Api
|
||||||
module V2
|
module V2
|
||||||
class TokensController < RestfulController
|
class TokensController < RestfulController
|
||||||
|
protect_from_forgery
|
||||||
|
|
||||||
def searchable_columns
|
def searchable_columns
|
||||||
[:description]
|
[:description]
|
||||||
end
|
end
|
||||||
|
@ -19,10 +22,10 @@ module Api
|
||||||
respond_with_resource
|
respond_with_resource
|
||||||
end
|
end
|
||||||
|
|
||||||
def my_tokens
|
private
|
||||||
authorize resource_class
|
|
||||||
instantiate_collection
|
def current_user
|
||||||
respond_with_collection
|
token_user || doorkeeper_user || method(:current_user).super_method.super_method.call
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Api
|
module Api
|
||||||
module V2
|
module V2
|
||||||
class TopicsController < RestfulController
|
class TopicsController < WithUpdatesController
|
||||||
def searchable_columns
|
def searchable_columns
|
||||||
[:name, :desc, :link]
|
%i[name desc link]
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,8 +1,10 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module Api
|
module Api
|
||||||
module V2
|
module V2
|
||||||
class UsersController < RestfulController
|
class UsersController < RestfulController
|
||||||
def current
|
def current
|
||||||
|
raise Pundit::NotAuthorizedError if current_user.nil?
|
||||||
@user = current_user
|
@user = current_user
|
||||||
authorize @user
|
authorize @user
|
||||||
show # delegate to the normal show function
|
show # delegate to the normal show function
|
||||||
|
@ -17,7 +19,7 @@ module Api
|
||||||
# only ask serializer to return is_admin field if we're on the
|
# only ask serializer to return is_admin field if we're on the
|
||||||
# current_user action
|
# current_user action
|
||||||
def default_scope
|
def default_scope
|
||||||
super.merge(show_is_admin: action_name == 'current')
|
super.merge(show_full_user: action_name == 'current')
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
28
app/controllers/api/v2/with_updates_controller.rb
Normal file
28
app/controllers/api/v2/with_updates_controller.rb
Normal file
|
@ -0,0 +1,28 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Api
|
||||||
|
module V2
|
||||||
|
class WithUpdatesController < RestfulController
|
||||||
|
def create
|
||||||
|
instantiate_resource
|
||||||
|
resource.user = current_user if current_user.present?
|
||||||
|
resource.updated_by = current_user if current_user.present?
|
||||||
|
authorize resource
|
||||||
|
create_action
|
||||||
|
respond_with_resource
|
||||||
|
end
|
||||||
|
|
||||||
|
def update
|
||||||
|
resource.updated_by = current_user if current_user.present?
|
||||||
|
update_action
|
||||||
|
respond_with_resource
|
||||||
|
end
|
||||||
|
|
||||||
|
def destroy
|
||||||
|
resource.updated_by = current_user if current_user.present?
|
||||||
|
destroy_action
|
||||||
|
head :no_content
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,4 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class ApplicationController < ActionController::Base
|
class ApplicationController < ActionController::Base
|
||||||
include ApplicationHelper
|
include ApplicationHelper
|
||||||
include Pundit
|
include Pundit
|
||||||
|
@ -21,23 +22,14 @@ class ApplicationController < ActionController::Base
|
||||||
helper_method :authenticated?
|
helper_method :authenticated?
|
||||||
helper_method :admin?
|
helper_method :admin?
|
||||||
|
|
||||||
def after_sign_in_path_for(resource)
|
|
||||||
sign_in_url = url_for(action: 'new', controller: 'sessions', only_path: false)
|
|
||||||
|
|
||||||
if request.referer == sign_in_url
|
|
||||||
super
|
|
||||||
elsif params[:uv_login] == '1'
|
|
||||||
'http://support.metamaps.cc/login_success?sso=' + current_sso_token
|
|
||||||
else
|
|
||||||
stored_location_for(resource) || request.referer || root_path
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
def handle_unauthorized
|
def handle_unauthorized
|
||||||
if authenticated?
|
if authenticated? && (params[:controller] == 'maps') && (params[:action] == 'show')
|
||||||
|
redirect_to request_access_map_path(params[:id])
|
||||||
|
elsif authenticated?
|
||||||
redirect_to root_path, notice: "You don't have permission to see that page."
|
redirect_to root_path, notice: "You don't have permission to see that page."
|
||||||
else
|
else
|
||||||
redirect_to new_user_session_path, notice: 'Try signing in to do that.'
|
store_location_for(resource, request.fullpath)
|
||||||
|
redirect_to sign_in_path, notice: 'Try signing in to do that.'
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -50,13 +42,13 @@ class ApplicationController < ActionController::Base
|
||||||
def require_no_user
|
def require_no_user
|
||||||
return true unless authenticated?
|
return true unless authenticated?
|
||||||
redirect_to edit_user_path(user), notice: 'You must be logged out.'
|
redirect_to edit_user_path(user), notice: 'You must be logged out.'
|
||||||
return false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def require_user
|
def require_user
|
||||||
return true if authenticated?
|
return true if authenticated?
|
||||||
redirect_to new_user_session_path, notice: 'You must be logged in.'
|
redirect_to sign_in_path, notice: 'You must be logged in.'
|
||||||
return false
|
false
|
||||||
end
|
end
|
||||||
|
|
||||||
def require_admin
|
def require_admin
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class ExploreController < ApplicationController
|
class ExploreController < ApplicationController
|
||||||
before_action :require_authentication, only: [:mine, :shared, :starred]
|
before_action :require_authentication, only: %i[mine shared starred]
|
||||||
before_action :authorize_explore
|
before_action :authorize_explore
|
||||||
after_action :verify_authorized
|
after_action :verify_authorized
|
||||||
after_action :verify_policy_scoped
|
after_action :verify_policy_scoped
|
||||||
|
|
|
@ -1,17 +1,18 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
# bad code that should be checked over before entering one of the
|
# bad code that should be checked over before entering one of the
|
||||||
# nice files from the right side of this repo
|
# nice files from the right side of this repo
|
||||||
class HacksController < ApplicationController
|
class HacksController < ApplicationController
|
||||||
include ActionView::Helpers::TextHelper # string truncate method
|
include ActionView::Helpers::TextHelper # string truncate method
|
||||||
|
|
||||||
# rate limited by rack-attack - currently 5r/s
|
# rate limited by rack-attack - currently 5r/s
|
||||||
# TODO: what else can we do to make get_with_redirects safer?
|
|
||||||
def load_url_title
|
def load_url_title
|
||||||
authorize :Hack
|
authorize :Hack
|
||||||
url = params[:url]
|
url = params[:url]
|
||||||
response, url = get_with_redirects(url)
|
response, url = get_with_redirects(url)
|
||||||
title = get_encoded_title(response)
|
title = get_encoded_title(response)
|
||||||
render json: { success: true, title: title, url: url }
|
render json: { success: true, title: title, url: url }
|
||||||
rescue StandardError => e
|
rescue StandardError
|
||||||
render json: { success: false }
|
render json: { success: false }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -28,7 +29,13 @@ class HacksController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_encoded_title(http_response)
|
def get_encoded_title(http_response)
|
||||||
title = http_response.body.sub(/.*<title>(.*)<\/title>.*/m, '\1')
|
# ensure there's actually an html title tag
|
||||||
|
title = http_response.body.sub(%r{.*(<title>.*</title>).*}m, '\1')
|
||||||
|
return '' unless title.starts_with?('<title>')
|
||||||
|
return '' unless title.ends_with?('</title>')
|
||||||
|
title = title.sub('<title>', '').sub(%r{</title>$}, '')
|
||||||
|
|
||||||
|
# encode and trim the title to 140 usable characters
|
||||||
charset = http_response['content-type'].sub(/.*charset=(.*);?.*/, '\1')
|
charset = http_response['content-type'].sub(/.*charset=(.*);?.*/, '\1')
|
||||||
charset = nil if charset == 'text/html'
|
charset = nil if charset == 'text/html'
|
||||||
title = title.force_encoding(charset) if charset
|
title = title.force_encoding(charset) if charset
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class MainController < ApplicationController
|
class MainController < ApplicationController
|
||||||
before_action :authorize_main
|
before_action :authorize_main
|
||||||
after_action :verify_authorized
|
after_action :verify_authorized
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class MappingsController < ApplicationController
|
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_authorized, except: :index
|
||||||
after_action :verify_policy_scoped, only: :index
|
after_action :verify_policy_scoped, only: :index
|
||||||
|
|
||||||
|
@ -19,10 +20,10 @@ class MappingsController < ApplicationController
|
||||||
@mapping = Mapping.new(mapping_params)
|
@mapping = Mapping.new(mapping_params)
|
||||||
authorize @mapping
|
authorize @mapping
|
||||||
@mapping.user = current_user
|
@mapping.user = current_user
|
||||||
|
@mapping.updated_by = current_user
|
||||||
|
|
||||||
if @mapping.save
|
if @mapping.save
|
||||||
render json: @mapping, status: :created
|
render json: @mapping, status: :created
|
||||||
Events::NewMapping.publish!(@mapping, current_user)
|
|
||||||
else
|
else
|
||||||
render json: @mapping.errors, status: :unprocessable_entity
|
render json: @mapping.errors, status: :unprocessable_entity
|
||||||
end
|
end
|
||||||
|
@ -32,8 +33,11 @@ class MappingsController < ApplicationController
|
||||||
def update
|
def update
|
||||||
@mapping = Mapping.find(params[:id])
|
@mapping = Mapping.find(params[:id])
|
||||||
authorize @mapping
|
authorize @mapping
|
||||||
|
@mapping.updated_by = current_user
|
||||||
|
@mapping.map.updated_by = current_user
|
||||||
|
@mapping.assign_attributes(mapping_params)
|
||||||
|
|
||||||
if @mapping.update_attributes(mapping_params)
|
if @mapping.save
|
||||||
head :no_content
|
head :no_content
|
||||||
else
|
else
|
||||||
render json: @mapping.errors, status: :unprocessable_entity
|
render json: @mapping.errors, status: :unprocessable_entity
|
||||||
|
@ -44,14 +48,8 @@ class MappingsController < ApplicationController
|
||||||
def destroy
|
def destroy
|
||||||
@mapping = Mapping.find(params[:id])
|
@mapping = Mapping.find(params[:id])
|
||||||
authorize @mapping
|
authorize @mapping
|
||||||
|
@mapping.updated_by = current_user
|
||||||
mappable = @mapping.mappable
|
@mapping.map.updated_by = current_user
|
||||||
if mappable.defer_to_map
|
|
||||||
mappable.permission = mappable.defer_to_map.permission
|
|
||||||
mappable.defer_to_map_id = nil
|
|
||||||
mappable.save
|
|
||||||
end
|
|
||||||
|
|
||||||
@mapping.destroy
|
@mapping.destroy
|
||||||
|
|
||||||
head :no_content
|
head :no_content
|
||||||
|
|
|
@ -1,14 +1,17 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class MapsController < ApplicationController
|
class MapsController < ApplicationController
|
||||||
before_action :require_user, only: [:create, :update, :destroy, :access, :events]
|
before_action :require_user, only: %i[create update destroy events follow unfollow]
|
||||||
before_action :set_map, only: [:show, :update, :destroy, :access, :contains,
|
before_action :set_map, only: %i[show conversation update destroy
|
||||||
:events, :export]
|
contains events export
|
||||||
|
follow unfollow unfollow_from_email]
|
||||||
after_action :verify_authorized
|
after_action :verify_authorized
|
||||||
|
|
||||||
# GET maps/:id
|
# GET maps/:id
|
||||||
def show
|
def show
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html do
|
format.html do
|
||||||
|
UserMap.where(map: @map, user: current_user).map(&:mark_invite_notifications_as_read)
|
||||||
@allmappers = @map.contributors
|
@allmappers = @map.contributors
|
||||||
@allcollaborators = @map.editors
|
@allcollaborators = @map.editors
|
||||||
@alltopics = policy_scope(@map.topics)
|
@alltopics = policy_scope(@map.topics)
|
||||||
|
@ -16,9 +19,28 @@ class MapsController < ApplicationController
|
||||||
@allmappings = policy_scope(@map.mappings)
|
@allmappings = policy_scope(@map.mappings)
|
||||||
@allmessages = @map.messages.sort_by(&:created_at)
|
@allmessages = @map.messages.sort_by(&:created_at)
|
||||||
@allstars = @map.stars
|
@allstars = @map.stars
|
||||||
|
@allrequests = @map.access_requests
|
||||||
end
|
end
|
||||||
format.json { render json: @map }
|
format.json { render json: @map }
|
||||||
format.csv { redirect_to action: :export, format: :csv }
|
format.csv { redirect_to action: :export, format: :csv }
|
||||||
|
format.ttl { redirect_to action: :export, format: :ttl }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
# GET maps/:id/conversation
|
||||||
|
def conversation
|
||||||
|
respond_to do |format|
|
||||||
|
format.html do
|
||||||
|
UserMap.where(map: @map, user: current_user).map(&:mark_invite_notifications_as_read)
|
||||||
|
@allmappers = @map.contributors
|
||||||
|
@allcollaborators = @map.editors
|
||||||
|
@alltopics = policy_scope(@map.topics)
|
||||||
|
@allsynapses = policy_scope(@map.synapses)
|
||||||
|
@allmappings = policy_scope(@map.mappings)
|
||||||
|
@allmessages = @map.messages.sort_by(&:created_at)
|
||||||
|
@allstars = @map.stars
|
||||||
|
@allrequests = @map.access_requests
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -40,6 +62,7 @@ class MapsController < ApplicationController
|
||||||
def create
|
def create
|
||||||
@map = Map.new(create_map_params)
|
@map = Map.new(create_map_params)
|
||||||
@map.user = current_user
|
@map.user = current_user
|
||||||
|
@map.updated_by = current_user
|
||||||
@map.arranged = false
|
@map.arranged = false
|
||||||
authorize @map
|
authorize @map
|
||||||
|
|
||||||
|
@ -60,8 +83,11 @@ class MapsController < ApplicationController
|
||||||
|
|
||||||
# PUT maps/:id
|
# PUT maps/:id
|
||||||
def update
|
def update
|
||||||
|
@map.updated_by = current_user
|
||||||
|
@map.assign_attributes(update_map_params)
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
if @map.update_attributes(update_map_params)
|
if @map.save
|
||||||
format.json { head :no_content }
|
format.json { head :no_content }
|
||||||
else
|
else
|
||||||
format.json { render json: @map.errors, status: :unprocessable_entity }
|
format.json { render json: @map.errors, status: :unprocessable_entity }
|
||||||
|
@ -71,7 +97,8 @@ class MapsController < ApplicationController
|
||||||
|
|
||||||
# DELETE maps/:id
|
# DELETE maps/:id
|
||||||
def destroy
|
def destroy
|
||||||
@map.delete
|
@map.updated_by = current_user
|
||||||
|
@map.destroy
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.json do
|
format.json do
|
||||||
|
@ -80,37 +107,21 @@ class MapsController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# POST maps/:id/access
|
|
||||||
def access
|
|
||||||
user_ids = params[:access] || []
|
|
||||||
|
|
||||||
@map.add_new_collaborators(user_ids).each do |user_id|
|
|
||||||
# add_new_collaborators returns array of added users,
|
|
||||||
# who we then send an email to
|
|
||||||
MapMailer.invite_to_edit_email(@map, current_user, User.find(user_id)).deliver_later
|
|
||||||
end
|
|
||||||
@map.remove_old_collaborators(user_ids)
|
|
||||||
|
|
||||||
respond_to do |format|
|
|
||||||
format.json do
|
|
||||||
render json: { message: 'Successfully altered edit permissions' }
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
# GET maps/:id/contains
|
# GET maps/:id/contains
|
||||||
def contains
|
def contains
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.json { render json: @map.contains(current_user) }
|
format.json { render json: @map.contains(current_user).as_json(user: current_user) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# GET maps/:id/export
|
# GET maps/:id/export
|
||||||
def export
|
def export
|
||||||
exporter = MapExportService.new(current_user, @map)
|
exporter = MapExportService.new(current_user, @map, base_url: request.base_url)
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.json { render json: exporter.json }
|
format.json { render json: exporter.json }
|
||||||
format.csv { send_data exporter.csv }
|
format.csv { send_data exporter.csv }
|
||||||
|
format.ttl { render text: exporter.rdf }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -120,9 +131,6 @@ class MapsController < ApplicationController
|
||||||
if params[:event] == 'conversation'
|
if params[:event] == 'conversation'
|
||||||
Events::ConversationStartedOnMap.publish!(@map, current_user)
|
Events::ConversationStartedOnMap.publish!(@map, current_user)
|
||||||
valid_event = true
|
valid_event = true
|
||||||
elsif params[:event] == 'user_presence'
|
|
||||||
Events::UserPresentOnMap.publish!(@map, current_user)
|
|
||||||
valid_event = true
|
|
||||||
end
|
end
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
|
@ -133,6 +141,43 @@ class MapsController < ApplicationController
|
||||||
end
|
end
|
||||||
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
|
private
|
||||||
|
|
||||||
def set_map
|
def set_map
|
||||||
|
@ -141,7 +186,7 @@ class MapsController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
def create_map_params
|
def create_map_params
|
||||||
params.permit(:name, :desc, :permission)
|
params.permit(:name, :desc, :permission, :source_id)
|
||||||
end
|
end
|
||||||
|
|
||||||
def update_map_params
|
def update_map_params
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class MessagesController < ApplicationController
|
class MessagesController < ApplicationController
|
||||||
before_action :require_user, except: [:show]
|
before_action :require_user, except: [:show]
|
||||||
after_action :verify_authorized
|
after_action :verify_authorized
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class MetacodeSetsController < ApplicationController
|
class MetacodeSetsController < ApplicationController
|
||||||
before_action :require_admin
|
before_action :require_admin
|
||||||
|
|
||||||
|
@ -55,8 +56,13 @@ class MetacodeSetsController < ApplicationController
|
||||||
@metacodes.each do |m|
|
@metacodes.each do |m|
|
||||||
InMetacodeSet.create(metacode_id: m, metacode_set_id: @metacode_set.id)
|
InMetacodeSet.create(metacode_id: m, metacode_set_id: @metacode_set.id)
|
||||||
end
|
end
|
||||||
format.html { redirect_to metacode_sets_url, notice: 'Metacode set was successfully created.' }
|
format.html do
|
||||||
format.json { render json: @metacode_set, status: :created, location: metacode_sets_url }
|
redirect_to metacode_sets_url,
|
||||||
|
notice: 'Metacode set was successfully created.'
|
||||||
|
end
|
||||||
|
format.json do
|
||||||
|
render json: @metacode_set, status: :created, location: metacode_sets_url
|
||||||
|
end
|
||||||
else
|
else
|
||||||
format.html { render action: 'new' }
|
format.html { render action: 'new' }
|
||||||
format.json { render json: @metacode_set.errors, status: :unprocessable_entity }
|
format.json { render json: @metacode_set.errors, status: :unprocessable_entity }
|
||||||
|
@ -73,20 +79,20 @@ class MetacodeSetsController < ApplicationController
|
||||||
if @metacode_set.update_attributes(metacode_set_params)
|
if @metacode_set.update_attributes(metacode_set_params)
|
||||||
|
|
||||||
# build an array of the IDs of the metacodes currently in the set
|
# build an array of the IDs of the metacodes currently in the set
|
||||||
@currentMetacodes = @metacode_set.metacodes.map { |m| m.id.to_s }
|
current_metacodes = @metacode_set.metacodes.map { |m| m.id.to_s }
|
||||||
# get the list of desired metacodes for the set from the user input and build an array out of it
|
# get the list of desired metacodes for the set from the user input and build an array out of it
|
||||||
@newMetacodes = params[:metacodes][:value].split(',')
|
new_metacodes = params[:metacodes][:value].split(',')
|
||||||
|
|
||||||
# remove the metacodes that were in it, but now aren't
|
# remove the metacodes that were in it, but now aren't
|
||||||
@removedMetacodes = @currentMetacodes - @newMetacodes
|
removed_metacodes = current_metacodes - new_metacodes
|
||||||
@removedMetacodes.each do |m|
|
removed_metacodes.each do |m|
|
||||||
@inmetacodeset = InMetacodeSet.find_by_metacode_id_and_metacode_set_id(m, @metacode_set.id)
|
inmetacodeset = InMetacodeSet.find_by(metacode_id: m, metacode_set_id: @metacode_set.id)
|
||||||
@inmetacodeset.destroy
|
inmetacodeset.destroy
|
||||||
end
|
end
|
||||||
|
|
||||||
# add the new metacodes
|
# add the new metacodes
|
||||||
@addedMetacodes = @newMetacodes - @currentMetacodes
|
added_metacodes = new_metacodes - current_metacodes
|
||||||
@addedMetacodes.each do |m|
|
added_metacodes.each do |m|
|
||||||
InMetacodeSet.create(metacode_id: m, metacode_set_id: @metacode_set.id)
|
InMetacodeSet.create(metacode_id: m, metacode_set_id: @metacode_set.id)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,8 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class MetacodesController < ApplicationController
|
class MetacodesController < ApplicationController
|
||||||
before_action :require_admin, except: [:index, :show]
|
before_action :require_admin, except: %i[index show]
|
||||||
before_action :set_metacode, only: [:edit, :update]
|
before_action :set_metacode, only: %i[edit update]
|
||||||
|
|
||||||
# GET /metacodes
|
# GET /metacodes
|
||||||
# GET /metacodes.json
|
# GET /metacodes.json
|
||||||
|
|
107
app/controllers/notifications_controller.rb
Normal file
107
app/controllers/notifications_controller.rb
Normal file
|
@ -0,0 +1,107 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class NotificationsController < ApplicationController
|
||||||
|
before_action :set_receipts, only: %i[index show mark_read mark_unread]
|
||||||
|
before_action :set_notification, only: %i[show mark_read mark_unread]
|
||||||
|
before_action :set_receipt, only: %i[show mark_read mark_unread]
|
||||||
|
|
||||||
|
def index
|
||||||
|
@notifications = current_user.mailbox.notifications.page(params[:page]).per(25)
|
||||||
|
respond_to do |format|
|
||||||
|
format.html
|
||||||
|
format.json do
|
||||||
|
notifications = @notifications.map do |notification|
|
||||||
|
receipt = @receipts.find_by(notification_id: notification.id)
|
||||||
|
NotificationDecorator.decorate(notification, receipt)
|
||||||
|
end
|
||||||
|
if !notifications.empty?
|
||||||
|
render json: notifications
|
||||||
|
else
|
||||||
|
render json: [].to_json
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def show
|
||||||
|
@receipt.update(is_read: true)
|
||||||
|
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)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
format.json do
|
||||||
|
render json: NotificationDecorator.decorate(@notification, @receipt)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def mark_read
|
||||||
|
@receipt.update(is_read: true)
|
||||||
|
respond_to do |format|
|
||||||
|
format.js
|
||||||
|
format.json do
|
||||||
|
render json: NotificationDecorator.decorate(@notification, @receipt)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def mark_unread
|
||||||
|
@receipt.update(is_read: false)
|
||||||
|
respond_to do |format|
|
||||||
|
format.js
|
||||||
|
format.json do
|
||||||
|
render json: NotificationDecorator.decorate(@notification, @receipt)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def unsubscribe
|
||||||
|
unsubscribe_redirect_if_logged_out!
|
||||||
|
check_if_already_unsubscribed!
|
||||||
|
return if performed? # if one of these checks already redirected, we're done
|
||||||
|
|
||||||
|
if current_user.update(emails_allowed: false)
|
||||||
|
redirect_to edit_user_path(current_user),
|
||||||
|
notice: 'You will no longer receive emails from Metamaps.'
|
||||||
|
else
|
||||||
|
flash[:alert] = 'Sorry, something went wrong. You have not been unsubscribed from emails.'
|
||||||
|
redirect_to edit_user_path(current_user)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def unsubscribe_redirect_if_logged_out!
|
||||||
|
return if current_user.present?
|
||||||
|
|
||||||
|
flash[:notice] = 'Continue to unsubscribe from emails by logging in.'
|
||||||
|
redirect_to "#{sign_in_path}?redirect_to=#{unsubscribe_notifications_path}"
|
||||||
|
end
|
||||||
|
|
||||||
|
def check_if_already_unsubscribed!
|
||||||
|
return if current_user.emails_allowed
|
||||||
|
|
||||||
|
redirect_to edit_user_path(current_user), notice: 'You were already unsubscribed from emails.'
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_receipts
|
||||||
|
@receipts = current_user.mailboxer_notification_receipts
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_notification
|
||||||
|
@notification = current_user.mailbox.notifications.find_by(id: params[:id])
|
||||||
|
end
|
||||||
|
|
||||||
|
def set_receipt
|
||||||
|
@receipt = @receipts.find_by(notification_id: params[:id])
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,4 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class SearchController < ApplicationController
|
class SearchController < ApplicationController
|
||||||
include TopicsHelper
|
include TopicsHelper
|
||||||
include MapsHelper
|
include MapsHelper
|
||||||
|
@ -7,14 +8,15 @@ class SearchController < ApplicationController
|
||||||
|
|
||||||
before_action :authorize_search
|
before_action :authorize_search
|
||||||
after_action :verify_authorized
|
after_action :verify_authorized
|
||||||
after_action :verify_policy_scoped, only: [:maps, :mappers, :synapses, :topics]
|
after_action :verify_policy_scoped, only: %i[maps mappers synapses topics]
|
||||||
|
|
||||||
# get /search/topics?term=SOMETERM
|
# get /search/topics?term=SOMETERM
|
||||||
def topics
|
def topics
|
||||||
term = params[:term]
|
term = params[:term]
|
||||||
user = params[:user] ? params[:user] : false
|
user = params[:user] ? params[:user] : false
|
||||||
|
|
||||||
if term && !term.empty? && term.downcase[0..3] != 'map:' && term.downcase[0..6] != 'mapper:' && !term.casecmp('topic:').zero?
|
if term.present? && term.downcase[0..3] != 'map:' &&
|
||||||
|
term.downcase[0..6] != 'mapper:' && !term.casecmp('topic:').zero?
|
||||||
|
|
||||||
# remove "topic:" if appended at beginning
|
# remove "topic:" if appended at beginning
|
||||||
term = term[6..-1] if term.downcase[0..5] == 'topic:'
|
term = term[6..-1] if term.downcase[0..5] == 'topic:'
|
||||||
|
@ -34,28 +36,28 @@ class SearchController < ApplicationController
|
||||||
end
|
end
|
||||||
|
|
||||||
# check whether there's a filter by metacode as part of the query
|
# check whether there's a filter by metacode as part of the query
|
||||||
filterByMetacode = false
|
filter_by_metacode = false
|
||||||
Metacode.all.each do |m|
|
Metacode.all.each do |m|
|
||||||
lOne = m.name.length + 1
|
length_one = m.name.length + 1
|
||||||
lTwo = m.name.length
|
length_two = m.name.length
|
||||||
|
|
||||||
if term.downcase[0..lTwo] == m.name.downcase + ':'
|
if term.downcase[0..length_two] == m.name.downcase + ':'
|
||||||
term = term[lOne..-1]
|
term = term[length_one..-1]
|
||||||
filterByMetacode = m
|
filter_by_metacode = m
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
search = '%' + term.downcase + '%'
|
search = '%' + term.downcase.strip + '%'
|
||||||
builder = policy_scope(Topic)
|
builder = policy_scope(Topic)
|
||||||
|
|
||||||
if filterByMetacode
|
if filter_by_metacode
|
||||||
if term == ''
|
if term == ''
|
||||||
builder = builder.none
|
builder = builder.none
|
||||||
else
|
else
|
||||||
builder = builder.where('LOWER("name") like ? OR
|
builder = builder.where('LOWER("name") like ? OR
|
||||||
LOWER("desc") like ? OR
|
LOWER("desc") like ? OR
|
||||||
LOWER("link") like ?', search, search, search)
|
LOWER("link") like ?', search, search, search)
|
||||||
builder = builder.where(metacode_id: filterByMetacode.id)
|
builder = builder.where(metacode_id: filter_by_metacode.id)
|
||||||
end
|
end
|
||||||
elsif desc
|
elsif desc
|
||||||
builder = builder.where('LOWER("desc") like ?', search)
|
builder = builder.where('LOWER("desc") like ?', search)
|
||||||
|
@ -70,6 +72,7 @@ class SearchController < ApplicationController
|
||||||
builder = builder.where(user: user) if user
|
builder = builder.where(user: user) if user
|
||||||
@topics = builder.order(:name)
|
@topics = builder.order(:name)
|
||||||
else
|
else
|
||||||
|
skip_policy_scope
|
||||||
@topics = []
|
@topics = []
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -81,7 +84,8 @@ class SearchController < ApplicationController
|
||||||
term = params[:term]
|
term = params[:term]
|
||||||
user = params[:user] ? params[:user] : nil
|
user = params[:user] ? params[:user] : nil
|
||||||
|
|
||||||
if term && !term.empty? && term.downcase[0..5] != 'topic:' && term.downcase[0..6] != 'mapper:' && !term.casecmp('map:').zero?
|
if term.present? && term.downcase[0..5] != 'topic:' &&
|
||||||
|
term.downcase[0..6] != 'mapper:' && !term.casecmp('map:').zero?
|
||||||
|
|
||||||
# remove "map:" if appended at beginning
|
# remove "map:" if appended at beginning
|
||||||
term = term[4..-1] if term.downcase[0..3] == 'map:'
|
term = term[4..-1] if term.downcase[0..3] == 'map:'
|
||||||
|
@ -93,7 +97,7 @@ class SearchController < ApplicationController
|
||||||
desc = true
|
desc = true
|
||||||
end
|
end
|
||||||
|
|
||||||
search = '%' + term.downcase + '%'
|
search = '%' + term.downcase.strip + '%'
|
||||||
builder = policy_scope(Map)
|
builder = policy_scope(Map)
|
||||||
|
|
||||||
builder = if desc
|
builder = if desc
|
||||||
|
@ -104,6 +108,7 @@ class SearchController < ApplicationController
|
||||||
builder = builder.where(user: user) if user
|
builder = builder.where(user: user) if user
|
||||||
@maps = builder.order(:name)
|
@maps = builder.order(:name)
|
||||||
else
|
else
|
||||||
|
skip_policy_scope
|
||||||
@maps = []
|
@maps = []
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -113,16 +118,17 @@ class SearchController < ApplicationController
|
||||||
# get /search/mappers?term=SOMETERM
|
# get /search/mappers?term=SOMETERM
|
||||||
def mappers
|
def mappers
|
||||||
term = params[:term]
|
term = params[:term]
|
||||||
if term && !term.empty? && term.downcase[0..3] != 'map:' && term.downcase[0..5] != 'topic:' && !term.casecmp('mapper:').zero?
|
if term.present? && term.downcase[0..3] != 'map:' &&
|
||||||
|
term.downcase[0..5] != 'topic:' && !term.casecmp('mapper:').zero?
|
||||||
|
|
||||||
# remove "mapper:" if appended at beginning
|
# remove "mapper:" if appended at beginning
|
||||||
term = term[7..-1] if term.downcase[0..6] == 'mapper:'
|
term = term[7..-1] if term.downcase[0..6] == 'mapper:'
|
||||||
search = term.downcase + '%'
|
search = term.downcase.strip + '%'
|
||||||
|
|
||||||
skip_policy_scope # TODO: builder = policy_scope(User)
|
builder = policy_scope(User).where('LOWER("name") like ?', search)
|
||||||
builder = User.where('LOWER("name") like ?', search)
|
|
||||||
@mappers = builder.order(:name)
|
@mappers = builder.order(:name)
|
||||||
else
|
else
|
||||||
|
skip_policy_scope
|
||||||
@mappers = []
|
@mappers = []
|
||||||
end
|
end
|
||||||
render json: autocomplete_user_array_json(@mappers).to_json
|
render json: autocomplete_user_array_json(@mappers).to_json
|
||||||
|
@ -135,16 +141,19 @@ class SearchController < ApplicationController
|
||||||
topic1id = params[:topic1id]
|
topic1id = params[:topic1id]
|
||||||
topic2id = params[:topic2id]
|
topic2id = params[:topic2id]
|
||||||
|
|
||||||
if term && !term.empty?
|
if term.present?
|
||||||
@synapses = policy_scope(Synapse).where('LOWER("desc") like ?', '%' + term.downcase + '%').order('"desc"')
|
@synapses = policy_scope(Synapse)
|
||||||
|
.where('LOWER("desc") like ?', '%' + term.downcase.strip + '%')
|
||||||
|
.order('"desc"')
|
||||||
|
|
||||||
@synapses = @synapses.uniq(&:desc)
|
@synapses = @synapses.uniq(&:desc)
|
||||||
elsif topic1id && !topic1id.empty?
|
elsif topic1id.present?
|
||||||
@one = policy_scope(Synapse).where(topic1_id: topic1id, topic2_id: topic2id)
|
one = policy_scope(Synapse).where(topic1_id: topic1id, topic2_id: topic2id)
|
||||||
@two = policy_scope(Synapse).where(topic2_id: topic1id, topic1_id: topic2id)
|
two = policy_scope(Synapse).where(topic2_id: topic1id, topic1_id: topic2id)
|
||||||
@synapses = @one + @two
|
@synapses = one + two
|
||||||
@synapses.sort! { |s1, s2| s1.desc <=> s2.desc }.to_a
|
@synapses.sort! { |s1, s2| s1.desc <=> s2.desc }.to_a
|
||||||
else
|
else
|
||||||
|
skip_policy_scope
|
||||||
@synapses = []
|
@synapses = []
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class StarsController < ApplicationController
|
class StarsController < ApplicationController
|
||||||
before_action :require_user
|
before_action :require_user
|
||||||
before_action :set_map
|
before_action :set_map
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class SynapsesController < ApplicationController
|
class SynapsesController < ApplicationController
|
||||||
include TopicsHelper
|
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_authorized, except: :index
|
||||||
after_action :verify_policy_scoped, only: :index
|
after_action :verify_policy_scoped, only: :index
|
||||||
|
|
||||||
|
@ -22,10 +23,20 @@ class SynapsesController < ApplicationController
|
||||||
@synapse = Synapse.new(synapse_params)
|
@synapse = Synapse.new(synapse_params)
|
||||||
@synapse.desc = '' if @synapse.desc.nil?
|
@synapse.desc = '' if @synapse.desc.nil?
|
||||||
@synapse.desc.strip! # no trailing/leading whitespace
|
@synapse.desc.strip! # no trailing/leading whitespace
|
||||||
authorize @synapse
|
@synapse.user = current_user
|
||||||
|
@synapse.updated_by = current_user
|
||||||
|
|
||||||
|
# we want invalid params to return :unprocessable_entity
|
||||||
|
# so we have to authorize AFTER saving. But if authorize
|
||||||
|
# fails, we need to rollback the SQL transaction
|
||||||
|
success = nil
|
||||||
|
ActiveRecord::Base.transaction do
|
||||||
|
success = @synapse.save
|
||||||
|
success ? authorize(@synapse) : skip_authorization
|
||||||
|
end
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
if @synapse.save
|
if success
|
||||||
format.json { render json: @synapse, status: :created }
|
format.json { render json: @synapse, status: :created }
|
||||||
else
|
else
|
||||||
format.json { render json: @synapse.errors, status: :unprocessable_entity }
|
format.json { render json: @synapse.errors, status: :unprocessable_entity }
|
||||||
|
@ -39,9 +50,11 @@ class SynapsesController < ApplicationController
|
||||||
@synapse = Synapse.find(params[:id])
|
@synapse = Synapse.find(params[:id])
|
||||||
@synapse.desc = '' if @synapse.desc.nil?
|
@synapse.desc = '' if @synapse.desc.nil?
|
||||||
authorize @synapse
|
authorize @synapse
|
||||||
|
@synapse.updated_by = current_user
|
||||||
|
@synapse.assign_attributes(synapse_params)
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
if @synapse.update_attributes(synapse_params)
|
if @synapse.save
|
||||||
format.json { head :no_content }
|
format.json { head :no_content }
|
||||||
else
|
else
|
||||||
format.json { render json: @synapse.errors, status: :unprocessable_entity }
|
format.json { render json: @synapse.errors, status: :unprocessable_entity }
|
||||||
|
@ -53,6 +66,7 @@ class SynapsesController < ApplicationController
|
||||||
def destroy
|
def destroy
|
||||||
@synapse = Synapse.find(params[:id])
|
@synapse = Synapse.find(params[:id])
|
||||||
authorize @synapse
|
authorize @synapse
|
||||||
|
@synapse.updated_by = current_user
|
||||||
@synapse.destroy
|
@synapse.destroy
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
|
@ -63,6 +77,8 @@ class SynapsesController < ApplicationController
|
||||||
private
|
private
|
||||||
|
|
||||||
def synapse_params
|
def synapse_params
|
||||||
params.require(:synapse).permit(:id, :desc, :category, :weight, :permission, :topic1_id, :topic2_id, :user_id)
|
params.require(:synapse).permit(
|
||||||
|
:id, :desc, :category, :weight, :permission, :topic1_id, :topic2_id
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
10
app/controllers/tokens_controller.rb
Normal file
10
app/controllers/tokens_controller.rb
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
class TokensController < ApplicationController
|
||||||
|
before_action :require_user, only: [:new]
|
||||||
|
|
||||||
|
def new
|
||||||
|
@token = Token.new(user: current_user)
|
||||||
|
render :new, layout: false
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,8 +1,12 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class TopicsController < ApplicationController
|
class TopicsController < ApplicationController
|
||||||
include TopicsHelper
|
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
|
after_action :verify_authorized, except: :autocomplete_topic
|
||||||
|
|
||||||
respond_to :html, :js, :json
|
respond_to :html, :js, :json
|
||||||
|
@ -10,26 +14,27 @@ class TopicsController < ApplicationController
|
||||||
# GET /topics/autocomplete_topic
|
# GET /topics/autocomplete_topic
|
||||||
def autocomplete_topic
|
def autocomplete_topic
|
||||||
term = params[:term]
|
term = params[:term]
|
||||||
if term && !term.empty?
|
if term.present?
|
||||||
@topics = policy_scope(Topic.where('LOWER("name") like ?', term.downcase + '%')).order('"name"')
|
topics = policy_scope(Topic)
|
||||||
@mapTopics = @topics.select { |t| t.metacode.name == 'Metamap' }
|
.where('LOWER("name") like ?', term.downcase + '%')
|
||||||
|
.order('"name"')
|
||||||
|
map_topics = topics.select { |t| t&.metacode&.name == 'Metamap' }
|
||||||
# prioritize topics which point to maps, over maps
|
# prioritize topics which point to maps, over maps
|
||||||
@exclude = @mapTopics.length > 0 ? @mapTopics.map(&:name) : ['']
|
exclude = map_topics.length.positive? ? map_topics.map(&:name) : ['']
|
||||||
@maps = policy_scope(Map.where('LOWER("name") like ? AND name NOT IN (?)', term.downcase + '%', @exclude)).order('"name"')
|
maps = policy_scope(Map)
|
||||||
|
.where('LOWER("name") like ? AND name NOT IN (?)', term.downcase + '%', exclude)
|
||||||
|
.order('"name"')
|
||||||
else
|
else
|
||||||
@topics = []
|
topics = []
|
||||||
@maps = []
|
maps = []
|
||||||
end
|
end
|
||||||
@all= @topics.to_a.concat(@maps.to_a).sort { |a, b| a.name <=> b.name }
|
@all = topics.to_a.concat(maps.to_a).sort_by(&:name)
|
||||||
|
|
||||||
render json: autocomplete_array_json(@all)
|
render json: autocomplete_array_json(@all).to_json
|
||||||
end
|
end
|
||||||
|
|
||||||
# GET topics/:id
|
# GET topics/:id
|
||||||
def show
|
def show
|
||||||
@topic = Topic.find(params[:id])
|
|
||||||
authorize @topic
|
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html do
|
format.html do
|
||||||
@alltopics = [@topic].concat(policy_scope(Topic.relatives(@topic.id, current_user)).to_a)
|
@alltopics = [@topic].concat(policy_scope(Topic.relatives(@topic.id, current_user)).to_a)
|
||||||
|
@ -39,15 +44,12 @@ class TopicsController < ApplicationController
|
||||||
|
|
||||||
respond_with(@allsynapses, @alltopics, @allcreators, @topic)
|
respond_with(@allsynapses, @alltopics, @allcreators, @topic)
|
||||||
end
|
end
|
||||||
format.json { render json: @topic }
|
format.json { render json: @topic.as_json(user: current_user).to_json }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# GET topics/:id/network
|
# GET topics/:id/network
|
||||||
def network
|
def network
|
||||||
@topic = Topic.find(params[:id])
|
|
||||||
authorize @topic
|
|
||||||
|
|
||||||
@alltopics = [@topic].concat(policy_scope(Topic.relatives(@topic.id, current_user)).to_a)
|
@alltopics = [@topic].concat(policy_scope(Topic.relatives(@topic.id, current_user)).to_a)
|
||||||
@allsynapses = policy_scope(Synapse.for_topic(@topic.id))
|
@allsynapses = policy_scope(Synapse.for_topic(@topic.id))
|
||||||
|
|
||||||
|
@ -55,9 +57,9 @@ class TopicsController < ApplicationController
|
||||||
@allcreators += @allsynapses.map(&:user).uniq
|
@allcreators += @allsynapses.map(&:user).uniq
|
||||||
|
|
||||||
@json = {}
|
@json = {}
|
||||||
@json['topic'] = @topic
|
@json['topic'] = @topic.as_json(user: current_user)
|
||||||
@json['creators'] = @allcreators
|
@json['creators'] = @allcreators
|
||||||
@json['relatives'] = @alltopics
|
@json['relatives'] = @alltopics.as_json(user: current_user)
|
||||||
@json['synapses'] = @allsynapses
|
@json['synapses'] = @allsynapses
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
|
@ -67,16 +69,13 @@ class TopicsController < ApplicationController
|
||||||
|
|
||||||
# GET topics/:id/relative_numbers
|
# GET topics/:id/relative_numbers
|
||||||
def relative_numbers
|
def relative_numbers
|
||||||
@topic = Topic.find(params[:id])
|
topics_already_has = params[:network] ? params[:network].split(',').map(&:to_i) : []
|
||||||
authorize @topic
|
|
||||||
|
|
||||||
topicsAlreadyHas = params[:network] ? params[:network].split(',').map(&:to_i) : []
|
|
||||||
|
|
||||||
alltopics = policy_scope(Topic.relatives(@topic.id, current_user)).to_a
|
alltopics = policy_scope(Topic.relatives(@topic.id, current_user)).to_a
|
||||||
alltopics.delete_if { |topic| topic.metacode_id != params[:metacode].to_i } if params[:metacode].present?
|
if params[:metacode].present?
|
||||||
alltopics.delete_if do |topic|
|
alltopics.delete_if { |topic| topic.metacode_id != params[:metacode].to_i }
|
||||||
!topicsAlreadyHas.index(topic.id).nil?
|
|
||||||
end
|
end
|
||||||
|
alltopics.delete_if { |topic| !topics_already_has.index(topic.id).nil? }
|
||||||
|
|
||||||
@json = Hash.new(0)
|
@json = Hash.new(0)
|
||||||
alltopics.each do |t|
|
alltopics.each do |t|
|
||||||
|
@ -90,15 +89,14 @@ class TopicsController < ApplicationController
|
||||||
|
|
||||||
# GET topics/:id/relatives
|
# GET topics/:id/relatives
|
||||||
def relatives
|
def relatives
|
||||||
@topic = Topic.find(params[:id])
|
topics_already_has = params[:network] ? params[:network].split(',').map(&:to_i) : []
|
||||||
authorize @topic
|
|
||||||
|
|
||||||
topicsAlreadyHas = params[:network] ? params[:network].split(',').map(&:to_i) : []
|
|
||||||
|
|
||||||
alltopics = policy_scope(Topic.relatives(@topic.id, current_user)).to_a
|
alltopics = policy_scope(Topic.relatives(@topic.id, current_user)).to_a
|
||||||
alltopics.delete_if { |topic| topic.metacode_id != params[:metacode].to_i } if params[:metacode].present?
|
if params[:metacode].present?
|
||||||
|
alltopics.delete_if { |topic| topic.metacode_id != params[:metacode].to_i }
|
||||||
|
end
|
||||||
alltopics.delete_if do |topic|
|
alltopics.delete_if do |topic|
|
||||||
!topicsAlreadyHas.index(topic.id.to_s).nil?
|
!topics_already_has.index(topic.id.to_s).nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
# find synapses between topics in alltopics array
|
# find synapses between topics in alltopics array
|
||||||
|
@ -108,13 +106,13 @@ class TopicsController < ApplicationController
|
||||||
!synapse_ids.index(synapse.id).nil?
|
!synapse_ids.index(synapse.id).nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
creatorsAlreadyHas = params[:creators] ? params[:creators].split(',').map(&:to_i) : []
|
creators_already_has = params[:creators] ? params[:creators].split(',').map(&:to_i) : []
|
||||||
allcreators = (alltopics.map(&:user) + allsynapses.map(&:user)).uniq.delete_if do |user|
|
allcreators = (alltopics.map(&:user) + allsynapses.map(&:user)).uniq.delete_if do |user|
|
||||||
!creatorsAlreadyHas.index(user.id).nil?
|
!creators_already_has.index(user.id).nil?
|
||||||
end
|
end
|
||||||
|
|
||||||
@json = {}
|
@json = {}
|
||||||
@json['topics'] = alltopics
|
@json['topics'] = alltopics.as_json(user: current_user)
|
||||||
@json['synapses'] = allsynapses
|
@json['synapses'] = allsynapses
|
||||||
@json['creators'] = allcreators
|
@json['creators'] = allcreators
|
||||||
|
|
||||||
|
@ -128,10 +126,12 @@ class TopicsController < ApplicationController
|
||||||
def create
|
def create
|
||||||
@topic = Topic.new(topic_params)
|
@topic = Topic.new(topic_params)
|
||||||
authorize @topic
|
authorize @topic
|
||||||
|
@topic.user = current_user
|
||||||
|
@topic.updated_by = current_user
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
if @topic.save
|
if @topic.save
|
||||||
format.json { render json: @topic, status: :created }
|
format.json { render json: @topic.as_json(user: current_user), status: :created }
|
||||||
else
|
else
|
||||||
format.json { render json: @topic.errors, status: :unprocessable_entity }
|
format.json { render json: @topic.errors, status: :unprocessable_entity }
|
||||||
end
|
end
|
||||||
|
@ -141,11 +141,11 @@ class TopicsController < ApplicationController
|
||||||
# PUT /topics/1
|
# PUT /topics/1
|
||||||
# PUT /topics/1.json
|
# PUT /topics/1.json
|
||||||
def update
|
def update
|
||||||
@topic = Topic.find(params[:id])
|
@topic.updated_by = current_user
|
||||||
authorize @topic
|
@topic.assign_attributes(topic_params)
|
||||||
|
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
if @topic.update_attributes(topic_params)
|
if @topic.save
|
||||||
format.json { head :no_content }
|
format.json { head :no_content }
|
||||||
else
|
else
|
||||||
format.json { render json: @topic.errors, status: :unprocessable_entity }
|
format.json { render json: @topic.errors, status: :unprocessable_entity }
|
||||||
|
@ -155,18 +155,58 @@ class TopicsController < ApplicationController
|
||||||
|
|
||||||
# DELETE topics/:id
|
# DELETE topics/:id
|
||||||
def destroy
|
def destroy
|
||||||
@topic = Topic.find(params[:id])
|
@topic.updated_by = current_user
|
||||||
authorize @topic
|
|
||||||
|
|
||||||
@topic.destroy
|
@topic.destroy
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.json { head :no_content }
|
format.json { head :no_content }
|
||||||
end
|
end
|
||||||
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
|
private
|
||||||
|
|
||||||
|
def set_topic
|
||||||
|
@topic = Topic.find(params[:id])
|
||||||
|
authorize @topic
|
||||||
|
end
|
||||||
|
|
||||||
def topic_params
|
def topic_params
|
||||||
params.require(:topic).permit(:id, :name, :desc, :link, :permission, :user_id, :metacode_id, :defer_to_map_id)
|
params.require(:topic).permit(:id, :name, :desc, :link, :permission, :metacode_id, :defer_to_map_id)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,12 +1,15 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
class Users::PasswordsController < Devise::PasswordsController
|
|
||||||
protected
|
|
||||||
|
|
||||||
def after_resetting_password_path_for(resource)
|
module Users
|
||||||
signed_in_root_path(resource)
|
class PasswordsController < Devise::PasswordsController
|
||||||
end
|
protected
|
||||||
|
|
||||||
def after_sending_reset_password_instructions_path_for(_resource_name)
|
def after_resetting_password_path_for(resource)
|
||||||
new_user_session_path if is_navigational_format?
|
signed_in_root_path(resource)
|
||||||
|
end
|
||||||
|
|
||||||
|
def after_sending_reset_password_instructions_path_for(_resource_name)
|
||||||
|
sign_in_path if is_navigational_format?
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,25 +1,40 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
class Users::RegistrationsController < Devise::RegistrationsController
|
|
||||||
before_action :configure_sign_up_params, only: [:create]
|
|
||||||
before_action :configure_account_update_params, only: [:update]
|
|
||||||
|
|
||||||
protected
|
module Users
|
||||||
|
class RegistrationsController < Devise::RegistrationsController
|
||||||
|
before_action :configure_sign_up_params, only: [:create]
|
||||||
|
before_action :configure_account_update_params, only: [:update]
|
||||||
|
after_action :store_location, only: [:new]
|
||||||
|
|
||||||
def after_sign_up_path_for(resource)
|
protected
|
||||||
signed_in_root_path(resource)
|
|
||||||
end
|
|
||||||
|
|
||||||
def after_update_path_for(resource)
|
def after_update_path_for(resource)
|
||||||
signed_in_root_path(resource)
|
signed_in_root_path(resource)
|
||||||
end
|
end
|
||||||
|
|
||||||
private
|
def after_sign_in_path_for(resource)
|
||||||
|
stored = stored_location_for(User)
|
||||||
|
return stored if stored
|
||||||
|
|
||||||
def configure_sign_up_params
|
if request.referer&.match(sign_in_url) || request.referer&.match(sign_up_url)
|
||||||
devise_parameter_sanitizer.permit(:sign_up, keys: [:name, :joinedwithcode])
|
super
|
||||||
end
|
else
|
||||||
|
request.referer || root_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
def configure_account_update_params
|
private
|
||||||
devise_parameter_sanitizer.permit(:account_update, keys: [:image])
|
|
||||||
|
def store_location
|
||||||
|
store_location_for(User, params[:redirect_to]) if params[:redirect_to]
|
||||||
|
end
|
||||||
|
|
||||||
|
def configure_sign_up_params
|
||||||
|
devise_parameter_sanitizer.permit(:sign_up, keys: %i[name joinedwithcode])
|
||||||
|
end
|
||||||
|
|
||||||
|
def configure_account_update_params
|
||||||
|
devise_parameter_sanitizer.permit(:account_update, keys: [:image])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
26
app/controllers/users/sessions_controller.rb
Normal file
26
app/controllers/users/sessions_controller.rb
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
# frozen_string_literal: true
|
||||||
|
|
||||||
|
module Users
|
||||||
|
class SessionsController < Devise::SessionsController
|
||||||
|
after_action :store_location, only: [:new]
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def after_sign_in_path_for(resource)
|
||||||
|
stored = stored_location_for(User)
|
||||||
|
return stored if stored
|
||||||
|
|
||||||
|
if request.referer&.match(sign_in_url) || request.referer&.match(sign_up_url)
|
||||||
|
super
|
||||||
|
else
|
||||||
|
request.referer || root_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private
|
||||||
|
|
||||||
|
def store_location
|
||||||
|
store_location_for(User, params[:redirect_to]) if params[:redirect_to]
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -1,6 +1,7 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
class UsersController < ApplicationController
|
class UsersController < ApplicationController
|
||||||
before_action :require_user, only: [:edit, :update, :updatemetacodes]
|
before_action :require_user, only: %i[edit update updatemetacodes update_metacode_focus]
|
||||||
|
|
||||||
respond_to :html, :json
|
respond_to :html, :json
|
||||||
|
|
||||||
|
@ -13,25 +14,25 @@ class UsersController < ApplicationController
|
||||||
|
|
||||||
# GET /users/:id/edit
|
# GET /users/:id/edit
|
||||||
def edit
|
def edit
|
||||||
@user = current_user
|
@user = User.find(current_user.id)
|
||||||
respond_with(@user)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# PUT /users/:id
|
# PUT /users/:id
|
||||||
def update
|
def update
|
||||||
@user = current_user
|
@user = User.find(current_user.id)
|
||||||
|
|
||||||
if user_params[:password] == '' && user_params[:password_confirmation] == ''
|
if user_params[:password] == '' && user_params[:password_confirmation] == ''
|
||||||
# not trying to change the password
|
# not trying to change the password
|
||||||
if @user.update_attributes(user_params.except(:password, :password_confirmation))
|
if @user.update_attributes(user_params.except(:password, :password_confirmation))
|
||||||
|
update_follow_settings(@user, params[:settings])
|
||||||
@user.image = nil if params[:remove_image] == '1'
|
@user.image = nil if params[:remove_image] == '1'
|
||||||
@user.save
|
@user.save
|
||||||
sign_in(@user, bypass: true)
|
bypass_sign_in(@user)
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html { redirect_to root_url, notice: 'Account updated!' }
|
format.html { redirect_to root_url, notice: 'Settings updated' }
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
sign_in(@user, bypass: true)
|
bypass_sign_in(@user)
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html { redirect_to edit_user_path(@user), notice: @user.errors.to_a[0] }
|
format.html { redirect_to edit_user_path(@user), notice: @user.errors.to_a[0] }
|
||||||
end
|
end
|
||||||
|
@ -41,11 +42,12 @@ class UsersController < ApplicationController
|
||||||
correct_pass = @user.valid_password?(params[:current_password])
|
correct_pass = @user.valid_password?(params[:current_password])
|
||||||
|
|
||||||
if correct_pass && @user.update_attributes(user_params)
|
if correct_pass && @user.update_attributes(user_params)
|
||||||
|
update_follow_settings(@user, params[:settings])
|
||||||
@user.image = nil if params[:remove_image] == '1'
|
@user.image = nil if params[:remove_image] == '1'
|
||||||
@user.save
|
@user.save
|
||||||
sign_in(@user, bypass: true)
|
sign_in(@user, bypass: true)
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
format.html { redirect_to root_url, notice: 'Account updated!' }
|
format.html { redirect_to root_url, notice: 'Settings updated' }
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
respond_to do |format|
|
respond_to do |format|
|
||||||
|
@ -93,9 +95,28 @@ class UsersController < ApplicationController
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# PUT /user/update_metacode_focus
|
||||||
|
def update_metacode_focus
|
||||||
|
@user = current_user
|
||||||
|
@user.settings.metacode_focus = params[:value]
|
||||||
|
@user.save
|
||||||
|
respond_to do |format|
|
||||||
|
format.json { render json: { success: 'success' } }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
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
|
def user_params
|
||||||
params.require(:user).permit(:name, :email, :image, :password, :password_confirmation)
|
params.require(:user).permit(
|
||||||
|
:name, :email, :image, :password, :password_confirmation, :emails_allowed, :settings
|
||||||
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
51
app/decorators/notification_decorator.rb
Normal file
51
app/decorators/notification_decorator.rb
Normal 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
|
|
@ -1,40 +1,14 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module ApplicationHelper
|
module ApplicationHelper
|
||||||
def metacodeset
|
|
||||||
metacodes = current_user.settings.metacodes
|
|
||||||
return false unless metacodes[0].include?('metacodeset')
|
|
||||||
if metacodes[0].sub('metacodeset-', '') == 'Most'
|
|
||||||
return 'Most'
|
|
||||||
elsif metacodes[0].sub('metacodeset-', '') == 'Recent'
|
|
||||||
return 'Recent'
|
|
||||||
end
|
|
||||||
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.mostUsedMetacodes).to_a
|
|
||||||
elsif set && set == 'Recent'
|
|
||||||
Metacode.where(id: current_user.recentMetacodes).to_a
|
|
||||||
elsif set
|
|
||||||
set.metacodes.to_a
|
|
||||||
else
|
|
||||||
Metacode.where(id: @m).to_a
|
|
||||||
end
|
|
||||||
@metacodes.sort! { |m1, m2| m2.name.downcase <=> m1.name.downcase }.rotate!(-1)
|
|
||||||
end
|
|
||||||
|
|
||||||
def user_most_used_metacodes
|
|
||||||
@metacodes = current_user.mostUsedMetacodes.map { |id| Metacode.find(id) }
|
|
||||||
end
|
|
||||||
|
|
||||||
def user_recent_metacodes
|
|
||||||
@metacodes = current_user.recentMetacodes.map { |id| Metacode.find(id) }
|
|
||||||
end
|
|
||||||
|
|
||||||
def invite_link
|
def invite_link
|
||||||
"#{request.base_url}/join" + (current_user ? "?code=#{current_user.code}" : '')
|
"#{request.base_url}/join" + (current_user ? "?code=#{current_user.code}" : '')
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def user_unread_notification_count
|
||||||
|
return 0 if current_user.nil?
|
||||||
|
@uunc ||= current_user.mailboxer_notification_receipts.reduce(0) do |total, receipt|
|
||||||
|
receipt.is_read ? total : total + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module ContentHelper
|
module ContentHelper
|
||||||
def resource_name
|
def resource_name
|
||||||
:user
|
:user
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module DeviseHelper
|
module DeviseHelper
|
||||||
def devise_error_messages!
|
def devise_error_messages!
|
||||||
resource.errors.to_a[0]
|
resource.errors.to_a[0]
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module InMetacodeSetsHelper
|
module InMetacodeSetsHelper
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
# frozen_string_literal: true
|
# frozen_string_literal: true
|
||||||
|
|
||||||
module MainHelper
|
module MainHelper
|
||||||
end
|
end
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue