make mapsWidth work and add mobile
This commit is contained in:
parent
9013d49ca1
commit
032d0d8f4b
17 changed files with 156 additions and 147 deletions
|
@ -169,9 +169,6 @@
|
|||
.upperRightMapButtons {
|
||||
right: 134px;
|
||||
}
|
||||
.mapPage .upperRightMapButtons, .topicPage .upperRightMapButtons {
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.upperRightIcon {
|
||||
width: 32px;
|
||||
|
@ -180,13 +177,7 @@
|
|||
background-repeat: no-repeat;
|
||||
cursor: pointer;
|
||||
}
|
||||
.mapPage .mapElement .importDialog {
|
||||
display: none;
|
||||
background-position: 0 0;
|
||||
}
|
||||
.mapPage.canEditMap .mapElement .importDialog {
|
||||
display: block;
|
||||
}
|
||||
|
||||
.sidebarFilterIcon {
|
||||
background-position: -32px 0;
|
||||
}
|
||||
|
@ -347,7 +338,7 @@
|
|||
|
||||
/* infoAndHelp */
|
||||
|
||||
.mapPage .openCheatsheet .tooltipsAbove, .topicPage .openCheatsheet .tooltipsAbove {
|
||||
.openCheatsheet .tooltipsAbove {
|
||||
right: 1px;
|
||||
left: auto;
|
||||
}
|
||||
|
@ -399,9 +390,6 @@
|
|||
background-position: 0 0;
|
||||
}
|
||||
|
||||
.unauthenticated .mapPage .starMap {
|
||||
display: none;
|
||||
}
|
||||
/* end infoAndHelp */
|
||||
|
||||
|
||||
|
@ -560,10 +548,6 @@
|
|||
left: -8px;
|
||||
}
|
||||
|
||||
.openCheatsheet .tooltipsAbove {
|
||||
left: -4px;
|
||||
}
|
||||
|
||||
.sidebarAccountIcon .tooltipsUnder {
|
||||
margin-left: -12px;
|
||||
margin-top: 40px;
|
||||
|
|
|
@ -35,5 +35,6 @@
|
|||
Metamaps.ServerData.mapIsStarred = <%= @map && current_user.starred_map?(@map) ? true : false %>
|
||||
</script>
|
||||
<% end %>
|
||||
<div class="hidden"><%= render :partial => 'shared/filterBox' %></div>
|
||||
<div id="loading"></div>
|
||||
<%= render :partial => 'layouts/foot' %>
|
||||
|
|
|
@ -2,27 +2,27 @@
|
|||
# @file
|
||||
# this code generates the list of icons in the filter box in the upper right menu area
|
||||
#%>
|
||||
|
||||
<%
|
||||
|
||||
<%
|
||||
@mappers = []
|
||||
@synapses = []
|
||||
@metacodes = []
|
||||
@metacodelist = ''
|
||||
@mapperlist = ''
|
||||
@synapselist = ''
|
||||
# There are essentially three functions happening here one to fill data to
|
||||
#@mappers with all people who have mapped on the selected map, which
|
||||
#actually gets checked twice once for topics or within @metacodes and once
|
||||
#for synapses on the map. @synapses get filled with all synapses on the map
|
||||
# There are essentially three functions happening here one to fill data to
|
||||
#@mappers with all people who have mapped on the selected map, which
|
||||
#actually gets checked twice once for topics or within @metacodes and once
|
||||
#for synapses on the map. @synapses get filled with all synapses on the map
|
||||
#and metacodes is filled with all the metacodes that are being used on the map.
|
||||
|
||||
if @map
|
||||
@alltopics.each_with_index do |topic, index|
|
||||
@alltopics.each_with_index do |topic, index|
|
||||
if @metacodes.index(topic.metacode) == nil
|
||||
@metacodes.push(topic.metacode)
|
||||
end
|
||||
end
|
||||
@allsynapses.each_with_index do |synapse, index|
|
||||
end
|
||||
@allsynapses.each_with_index do |synapse, index|
|
||||
if @synapses.index{|s| s.desc == synapse.desc} == nil
|
||||
@synapses.push(synapse)
|
||||
end
|
||||
|
@ -32,16 +32,16 @@
|
|||
@mappers.push(mapping.user)
|
||||
end
|
||||
end
|
||||
elsif @topic
|
||||
@alltopics.each_with_index do |topic, index|
|
||||
elsif @topic
|
||||
@alltopics.each_with_index do |topic, index|
|
||||
if @metacodes.index(topic.metacode) == nil
|
||||
@metacodes.push(topic.metacode)
|
||||
end
|
||||
if @mappers.index(topic.user) == nil
|
||||
@mappers.push(topic.user)
|
||||
end
|
||||
end
|
||||
@allsynapses.each_with_index do |synapse, index|
|
||||
end
|
||||
@allsynapses.each_with_index do |synapse, index|
|
||||
if @synapses.index{|s| s.desc == synapse.desc} == nil
|
||||
@synapses.push(synapse)
|
||||
end
|
||||
|
@ -52,7 +52,7 @@
|
|||
end
|
||||
|
||||
if @map || @topic
|
||||
@metacodes.sort! {|x,y|
|
||||
@metacodes.sort! {|x,y|
|
||||
n1 = x.name || ""
|
||||
n2 = y.name || ""
|
||||
n1 <=> n2
|
||||
|
@ -62,24 +62,24 @@
|
|||
d2 = y.desc || ""
|
||||
d1 <=> d2
|
||||
}
|
||||
@mappers.sort! {|x,y|
|
||||
@mappers.sort! {|x,y|
|
||||
n1 = x.name || ""
|
||||
n2 = y.name || ""
|
||||
n1 <=> n2
|
||||
n1 <=> n2
|
||||
}
|
||||
|
||||
@metacodes.each_with_index do |metacode, index|
|
||||
|
||||
@metacodes.each_with_index do |metacode, index|
|
||||
@metacodelist += '<li data-id="' + metacode.id.to_s + '">'
|
||||
@metacodelist += '<img src="' + asset_path(metacode.icon) + '" data-id="' + metacode.id.to_s + '" alt="' + metacode.name + '" />'
|
||||
@metacodelist += '<p>' + metacode.name.downcase + '</p></li>'
|
||||
end
|
||||
@synapses.each_with_index do |synapse, index|
|
||||
@synapses.each_with_index do |synapse, index|
|
||||
d = synapse.desc || ""
|
||||
@synapselist += '<li data-id="' + d + '">'
|
||||
@synapselist += '<img src="' + asset_path('synapse16.png') + '" alt="synapse icon" /><p>' + d
|
||||
@synapselist += '</p></li>'
|
||||
end
|
||||
@mappers.each_with_index do |mapper, index|
|
||||
end
|
||||
@mappers.each_with_index do |mapper, index|
|
||||
@mapperlist += '<li data-id="' + mapper.id.to_s + '">'
|
||||
@mapperlist += '<img src="' + mapper.image.url(:sixtyfour) + '" data-id="' + mapper.id.to_s + '" alt="' + mapper.name + '" />'
|
||||
@mapperlist += '<p>' + mapper.name + '</p></li>'
|
||||
|
@ -95,7 +95,7 @@
|
|||
<div class="clearfloat"></div>
|
||||
<ul>
|
||||
<%= @mapperlist.html_safe %>
|
||||
</ul>
|
||||
</ul>
|
||||
<div class="clearfloat"></div>
|
||||
</div>
|
||||
|
||||
|
@ -106,7 +106,7 @@
|
|||
<div class="clearfloat"></div>
|
||||
<ul>
|
||||
<%= @metacodelist.html_safe %>
|
||||
</ul>
|
||||
</ul>
|
||||
<div class="clearfloat"></div>
|
||||
</div>
|
||||
|
||||
|
@ -117,9 +117,8 @@
|
|||
<div class="clearfloat"></div>
|
||||
<ul>
|
||||
<%= @synapselist.html_safe %>
|
||||
</ul>
|
||||
</ul>
|
||||
<div class="clearfloat"></div>
|
||||
</div>
|
||||
|
||||
</div> <!-- end .filterBox -->
|
||||
|
||||
|
|
|
@ -26,8 +26,6 @@ const Filter = {
|
|||
init: function() {
|
||||
var self = Filter
|
||||
|
||||
$('.sidebarFilterIcon').click(self.toggleBox)
|
||||
|
||||
$('.sidebarFilterBox .showAllMetacodes').click(self.filterNoMetacodes)
|
||||
$('.sidebarFilterBox .showAllSynapses').click(self.filterNoSynapses)
|
||||
$('.sidebarFilterBox .showAllMappers').click(self.filterNoMappers)
|
||||
|
|
|
@ -19,7 +19,7 @@ const ImportDialog = {
|
|||
self.closeLightbox = closeLightbox
|
||||
|
||||
$('#lightbox_content').append($(outdent`
|
||||
<div class="lightboxContent" id="import-dialog-lightbox">
|
||||
<div class="lightboxContent" id="import-dialog">
|
||||
<div class="importDialogWrapper" />
|
||||
</div>
|
||||
`))
|
||||
|
|
|
@ -3,30 +3,42 @@
|
|||
import React from 'react'
|
||||
import ReactDOM from 'react-dom'
|
||||
import { Router, browserHistory } from 'react-router'
|
||||
|
||||
import { merge } from 'lodash'
|
||||
|
||||
import { notifyUser } from './index.js'
|
||||
import ImportDialog from './ImportDialog'
|
||||
import Active from '../Active'
|
||||
import DataModel from '../DataModel'
|
||||
import { ExploreMaps, ChatView, TopicCard } from '../Views'
|
||||
import Filter from '../Filter'
|
||||
import JIT from '../JIT'
|
||||
import Realtime from '../Realtime'
|
||||
import Map, { InfoBox } from '../Map'
|
||||
import Topic from '../Topic'
|
||||
import Visualize from '../Visualize'
|
||||
import makeRoutes from '../../components/makeRoutes'
|
||||
let routes
|
||||
|
||||
// 220 wide + 16 padding on both sides
|
||||
const MAP_WIDTH = 252
|
||||
const MOBILE_VIEW_BREAKPOINT = 504
|
||||
const MOBILE_VIEW_PADDING = 40
|
||||
const MAX_COLUMNS = 4
|
||||
|
||||
const ReactApp = {
|
||||
mapId: null,
|
||||
unreadNotificationsCount: 0,
|
||||
mapIsStarred: false,
|
||||
init: function(serverData) {
|
||||
mapsWidth: 0,
|
||||
mobile: false,
|
||||
init: function(serverData, openLightbox) {
|
||||
const self = ReactApp
|
||||
self.unreadNotificationsCount = serverData.unreadNotificationsCount
|
||||
self.mapIsStarred = serverData.mapIsStarred
|
||||
self.openLightbox = openLightbox
|
||||
routes = makeRoutes()
|
||||
self.resize()
|
||||
self.setMobile()
|
||||
self.render()
|
||||
window && window.addEventListener('resize', self.resize)
|
||||
},
|
||||
handleUpdate: function(location) {
|
||||
const self = ReactApp
|
||||
|
@ -59,7 +71,8 @@ const ReactApp = {
|
|||
const self = ReactApp
|
||||
return merge({
|
||||
unreadNotificationsCount: self.unreadNotificationsCount,
|
||||
currentUser: Active.Mapper
|
||||
currentUser: Active.Mapper,
|
||||
mobile: self.mobile
|
||||
},
|
||||
self.getMapProps(),
|
||||
self.getTopicProps(),
|
||||
|
@ -72,13 +85,21 @@ const ReactApp = {
|
|||
return {
|
||||
mapId: self.mapId,
|
||||
map: Active.Map,
|
||||
mapIsStarred: self.mapIsStarred,
|
||||
mapIsStarred: Map.mapIsStarred,
|
||||
endActiveMap: Map.end,
|
||||
launchNewMap: Map.launch,
|
||||
toggleMapInfoBox: InfoBox.toggleBox,
|
||||
infoBoxHtml: InfoBox.html,
|
||||
toggleFilterBox: Filter.toggleBox,
|
||||
infoBoxHtml: InfoBox.html
|
||||
// filters
|
||||
filterBoxHtml: $('.filterBox')[0].outerHTML,
|
||||
openImportLightbox: () => ImportDialog.show(),
|
||||
forkMap: Map.fork,
|
||||
openHelpLightbox: () => self.openLightbox('cheatsheet'),
|
||||
onMapStar: Map.star,
|
||||
onMapUnstar: Map.unstar,
|
||||
onZoomExtents: event => JIT.zoomExtents(event, Visualize.mGraph.canvas),
|
||||
onZoomIn: JIT.zoomIn,
|
||||
onZoomOut: JIT.zoomOut
|
||||
}
|
||||
},
|
||||
getTopicCardProps: function() {
|
||||
|
@ -109,7 +130,8 @@ const ReactApp = {
|
|||
pending: ExploreMaps.pending,
|
||||
onStar: ExploreMaps.onStar,
|
||||
onRequest: ExploreMaps.onRequest,
|
||||
onMapFollow: ExploreMaps.onMapFollow
|
||||
onMapFollow: ExploreMaps.onMapFollow,
|
||||
mapsWidth: ReactApp.mapsWidth
|
||||
}
|
||||
},
|
||||
getChatProps: function() {
|
||||
|
@ -132,6 +154,24 @@ const ReactApp = {
|
|||
inputFocus: ChatView.inputFocus,
|
||||
handleInputMessage: ChatView.handleInputMessage
|
||||
}
|
||||
},
|
||||
setMobile: function() {
|
||||
const self = ReactApp
|
||||
self.mobile = document && document.body.clientWidth <= MOBILE_VIEW_BREAKPOINT
|
||||
self.render()
|
||||
},
|
||||
resize: function() {
|
||||
const self = ReactApp
|
||||
const maps = ExploreMaps.collection
|
||||
const currentUser = Active.Mapper
|
||||
const user = maps && maps.id === 'mapper' ? ExploreMaps.mapper : null
|
||||
const numCards = (maps ? maps.length : 0) + (user || currentUser ? 1 : 0)
|
||||
const mapSpaces = Math.floor(document.body.clientWidth / MAP_WIDTH)
|
||||
const mapsWidth = document.body.clientWidth <= MOBILE_VIEW_BREAKPOINT
|
||||
? document.body.clientWidth - MOBILE_VIEW_PADDING
|
||||
: Math.min(MAX_COLUMNS, Math.min(numCards, mapSpaces)) * MAP_WIDTH
|
||||
self.mapsWidth = mapsWidth
|
||||
self.render()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -18,7 +18,7 @@ const GlobalUI = {
|
|||
init: function(serverData) {
|
||||
const self = GlobalUI
|
||||
|
||||
self.ReactApp.init(serverData)
|
||||
self.ReactApp.init(serverData, self.openLightbox)
|
||||
self.Search.init(serverData)
|
||||
self.CreateMap.init(serverData)
|
||||
self.Account.init(serverData)
|
||||
|
|
|
@ -50,15 +50,6 @@ const JIT = {
|
|||
*/
|
||||
init: function(serverData) {
|
||||
const self = JIT
|
||||
|
||||
$('.zoomIn').click(self.zoomIn)
|
||||
$('.zoomOut').click(self.zoomOut)
|
||||
|
||||
const zoomExtents = function(event) {
|
||||
self.zoomExtents(event, Visualize.mGraph.canvas)
|
||||
}
|
||||
$('.zoomExtents').click(zoomExtents)
|
||||
|
||||
self.topicDescImage = new Image()
|
||||
self.topicDescImage.src = serverData['topic_description_signifier.png']
|
||||
|
||||
|
|
|
@ -9,7 +9,7 @@ import Create from '../Create'
|
|||
import DataModel from '../DataModel'
|
||||
import DataModelMap from '../DataModel/Map'
|
||||
import Filter from '../Filter'
|
||||
import GlobalUI from '../GlobalUI'
|
||||
import GlobalUI, { ReactApp } from '../GlobalUI'
|
||||
import JIT from '../JIT'
|
||||
import Loading from '../Loading'
|
||||
import Realtime from '../Realtime'
|
||||
|
@ -25,26 +25,18 @@ const Map = {
|
|||
events: {
|
||||
editedByActiveMapper: 'Metamaps:Map:events:editedByActiveMapper'
|
||||
},
|
||||
mapIsStarred: false,
|
||||
init: function(serverData) {
|
||||
var self = Map
|
||||
|
||||
self.mapIsStarred = serverData.mapIsStarred
|
||||
|
||||
$('#wrapper').mousedown(function(e) {
|
||||
if (e.button === 1) return false
|
||||
})
|
||||
|
||||
$('.starMap').click(function() {
|
||||
if ($(this).is('.starred')) self.unstar()
|
||||
else self.star()
|
||||
})
|
||||
|
||||
$('.sidebarFork').click(function() {
|
||||
self.fork()
|
||||
})
|
||||
|
||||
GlobalUI.CreateMap.emptyForkMapForm = $('#fork_map').html()
|
||||
|
||||
self.updateStar()
|
||||
|
||||
InfoBox.init(serverData, function updateThumbnail() {
|
||||
self.uploadMapScreenshot()
|
||||
})
|
||||
|
@ -102,8 +94,6 @@ const Map = {
|
|||
$('.wrapper').addClass('commonsMap')
|
||||
}
|
||||
|
||||
Map.updateStar()
|
||||
|
||||
// set filter mapper H3 text
|
||||
$('#filter_by_mapper h3').html('MAPPERS')
|
||||
|
||||
|
@ -153,17 +143,6 @@ const Map = {
|
|||
$('.viewOnly').removeClass('isViewOnly')
|
||||
}
|
||||
},
|
||||
updateStar: function() {
|
||||
if (!Active.Mapper || !DataModel.Stars) return
|
||||
// update the star/unstar icon
|
||||
if (DataModel.Stars.find(function(s) { return s.user_id === Active.Mapper.id })) {
|
||||
$('.starMap').addClass('starred')
|
||||
$('.starMap .tooltipsAbove').html('Unstar')
|
||||
} else {
|
||||
$('.starMap').removeClass('starred')
|
||||
$('.starMap .tooltipsAbove').html('Star')
|
||||
}
|
||||
},
|
||||
star: function() {
|
||||
var self = Map
|
||||
|
||||
|
@ -172,7 +151,8 @@ const Map = {
|
|||
DataModel.Stars.push({ user_id: Active.Mapper.id, map_id: Active.Map.id })
|
||||
DataModel.Maps.Starred.add(Active.Map)
|
||||
GlobalUI.notifyUser('Map is now starred')
|
||||
self.updateStar()
|
||||
self.mapIsStarred = true
|
||||
ReactApp.render()
|
||||
},
|
||||
unstar: function() {
|
||||
var self = Map
|
||||
|
@ -181,7 +161,8 @@ const Map = {
|
|||
$.post('/maps/' + Active.Map.id + '/unstar')
|
||||
DataModel.Stars = DataModel.Stars.filter(function(s) { return s.user_id !== Active.Mapper.id })
|
||||
DataModel.Maps.Starred.remove(Active.Map)
|
||||
self.updateStar()
|
||||
self.mapIsStarred = false
|
||||
ReactApp.render()
|
||||
},
|
||||
fork: function() {
|
||||
GlobalUI.openLightbox('forkmap')
|
||||
|
|
|
@ -60,6 +60,7 @@ const ExploreMaps = {
|
|||
},
|
||||
render: function() {
|
||||
var self = ExploreMaps
|
||||
ReactApp.resize()
|
||||
ReactApp.render()
|
||||
Loading.hide()
|
||||
},
|
||||
|
|
|
@ -23,13 +23,13 @@ class App extends Component {
|
|||
}
|
||||
|
||||
render () {
|
||||
const { toast, currentUser, unreadNotificationsCount } = this.props
|
||||
const { children, toast, currentUser, unreadNotificationsCount } = this.props
|
||||
return <div className="wrapper" id="wrapper">
|
||||
<UpperLeftUI currentUser={currentUser} />
|
||||
<UpperRightUI currentUser={currentUser} unreadNotificationsCount={unreadNotificationsCount} />
|
||||
<Toast message={toast} />
|
||||
{currentUser && <a className='feedback-icon' target='_blank' href='https://hylo.com/c/metamaps'></a>}
|
||||
{this.props.children}
|
||||
{children}
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,10 +2,14 @@ import React, { Component, PropTypes } from 'react'
|
|||
|
||||
class FilterBox extends Component {
|
||||
static propTypes = {
|
||||
isMap: PropTypes.bool,
|
||||
filterBoxHtml: PropTypes.string
|
||||
}
|
||||
|
||||
render () {
|
||||
return null
|
||||
const { filterBoxHtml } = this.props
|
||||
const html = {__html: filterBoxHtml}
|
||||
return <div className="sidebarFilterBox upperRightBox" dangerouslySetInnerHTML={html}></div>
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -7,23 +7,28 @@ class InfoAndHelp extends Component {
|
|||
mapIsStarred: PropTypes.bool,
|
||||
currentUser: PropTypes.object,
|
||||
map: PropTypes.object,
|
||||
onHelpClick: PropTypes.func,
|
||||
onMapStar: PropTypes.func,
|
||||
onMapUnstar: PropTypes.func,
|
||||
|
||||
onInfoClick: PropTypes.func,
|
||||
infoBoxhtml: PropTypes.string
|
||||
}
|
||||
|
||||
render () {
|
||||
const { mapIsStarred, map, currentUser, onInfoClick, infoBoxHtml } = this.props
|
||||
const { mapIsStarred, map, currentUser, onInfoClick, infoBoxHtml, onMapStar, onMapUnstar, onHelpClick } = this.props
|
||||
const starclassName = mapIsStarred ? 'starred' : ''
|
||||
const tooltip = mapIsStarred ? 'Star' : 'Unstar'
|
||||
const tooltip = mapIsStarred ? 'Unstar' : 'Star'
|
||||
const onStarClick = mapIsStarred ? onMapUnstar : onMapStar
|
||||
return <div className="infoAndHelp">
|
||||
<MapInfoBox map={map} currentUser={currentUser} infoBoxHtml={infoBoxHtml} />
|
||||
<div className={`starMap infoElement mapElement ${starclassName}`}>
|
||||
<div className={`starMap infoElement mapElement ${starclassName}`} onClick={onStarClick}>
|
||||
<div className="tooltipsAbove">{tooltip}</div>
|
||||
</div>
|
||||
<div className="mapInfoIcon infoElement mapElement" onClick={onInfoClick}>
|
||||
<div className="tooltipsAbove">Map Info</div>
|
||||
</div>
|
||||
<div className="openCheatsheet openLightbox infoElement mapElement" data-open="cheatsheet">
|
||||
<div className="openCheatsheet infoElement mapElement" onClick={onHelpClick}>
|
||||
<div className="tooltipsAbove">Help</div>
|
||||
</div>
|
||||
<div className="clearfloat"></div>
|
||||
|
|
|
@ -5,25 +5,31 @@ import FilterBox from './FilterBox'
|
|||
class MapButtons extends Component {
|
||||
static propTypes = {
|
||||
currentUser: PropTypes.object,
|
||||
filterBoxOpen: PropTypes.bool
|
||||
canEditMap: PropTypes.bool,
|
||||
onImportClick: PropTypes.func,
|
||||
onForkClick: PropTypes.func,
|
||||
onFilterClick: PropTypes.func,
|
||||
filterBoxHtml: PropTypes.string
|
||||
}
|
||||
|
||||
render () {
|
||||
const { currentUser, filterBoxOpen } = this.props
|
||||
const { currentUser, canEditMap, filterBoxHtml, onFilterClick, onImportClick, onForkClick } = this.props
|
||||
return <div className="mapElement upperRightEl upperRightMapButtons upperRightUI">
|
||||
{currentUser && <div className="importDialog upperRightEl upperRightIcon mapElement openLightbox" data-open="import-dialog-lightbox">
|
||||
{canEditMap && <div className="importDialog upperRightEl upperRightIcon mapElement" onClick={onImportClick}>
|
||||
<div className="tooltipsUnder">
|
||||
Import Data
|
||||
</div>
|
||||
</div>}
|
||||
<div className="sidebarFilter upperRightEl">
|
||||
<div className="sidebarFilterIcon upperRightIcon"><div className="tooltipsUnder">Filter</div></div>
|
||||
{filterBoxOpen && <div className="sidebarFilterBox upperRightBox">
|
||||
<FilterBox />
|
||||
</div>}
|
||||
<div className="sidebarFilterIcon upperRightIcon" onClick={onFilterClick}>
|
||||
<div className="tooltipsUnder">Filter</div>
|
||||
</div>
|
||||
<FilterBox filterBoxHtml={filterBoxHtml} />
|
||||
</div>
|
||||
{currentUser && <div className="sidebarFork upperRightEl">
|
||||
<div className="sidebarForkIcon upperRightIcon"><div className="tooltipsUnder">Save To New Map</div></div>
|
||||
<div className="sidebarForkIcon upperRightIcon" onClick={onForkClick}>
|
||||
<div className="tooltipsUnder">Save To New Map</div>
|
||||
</div>
|
||||
</div>}
|
||||
<div className="clearfloat"></div>
|
||||
</div>
|
||||
|
|
|
@ -2,13 +2,23 @@ import React, { Component, PropTypes } from 'react'
|
|||
|
||||
class MapControls extends Component {
|
||||
static propTypes = {
|
||||
onClickZoomExtents: PropTypes.func,
|
||||
onClickZoomIn: PropTypes.func,
|
||||
onClickZoomOut: PropTypes.func
|
||||
}
|
||||
|
||||
render () {
|
||||
const { onClickZoomExtents, onClickZoomIn, onClickZoomOut } = this.props
|
||||
return <div className="mapControls mapElement">
|
||||
<div className="zoomExtents mapControl"><div className="tooltips">Center View</div></div>
|
||||
<div className="zoomIn mapControl"><div className="tooltips">Zoom In</div></div>
|
||||
<div className="zoomOut mapControl"><div className="tooltips">Zoom Out</div></div>
|
||||
<div className="zoomExtents mapControl" onClick={onClickZoomExtents}>
|
||||
<div className="tooltips">Center View</div>
|
||||
</div>
|
||||
<div className="zoomIn mapControl" onClick={onClickZoomIn}>
|
||||
<div className="tooltips">Zoom In</div>
|
||||
</div>
|
||||
<div className="zoomOut mapControl" onClick={onClickZoomOut}>
|
||||
<div className="tooltips">Zoom Out</div>
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
}
|
||||
|
|
|
@ -14,6 +14,7 @@ class MapView extends Component {
|
|||
map: PropTypes.object,
|
||||
mapIsStarred: PropTypes.bool,
|
||||
toggleFilterBox: PropTypes.func,
|
||||
filterBoxHtml: PropTypes.string,
|
||||
toggleMapInfoBox: PropTypes.func,
|
||||
infoBoxHtml: PropTypes.string,
|
||||
currentUser: PropTypes.object,
|
||||
|
@ -62,7 +63,11 @@ class MapView extends Component {
|
|||
}
|
||||
|
||||
render = () => {
|
||||
const { map, mapIsStarred, currentUser, onOpen, onClose, toggleMapInfoBox, toggleFilterBox, infoBoxHtml } = this.props
|
||||
const { map, currentUser, onOpen, onClose,
|
||||
toggleMapInfoBox, toggleFilterBox, infoBoxHtml, filterBoxHtml,
|
||||
openImportLightbox, forkMap, openHelpLightbox,
|
||||
mapIsStarred, onMapStar, onMapUnstar,
|
||||
onZoomExtents, onZoomIn, onZoomOut } = this.props
|
||||
const { filterBoxOpen, chatOpen } = this.state
|
||||
const onChatOpen = () => {
|
||||
this.setState({chatOpen: true})
|
||||
|
@ -72,17 +77,28 @@ class MapView extends Component {
|
|||
this.setState({chatOpen: false})
|
||||
onClose()
|
||||
}
|
||||
const canEditMap = map && map.authorizeToEdit(currentUser)
|
||||
// TODO: stop using {...this.props} and make explicit
|
||||
return <div className="mapWrapper">
|
||||
<MapButtons currentUser={currentUser} onFilterClick={toggleFilterBox} />
|
||||
<MapButtons currentUser={currentUser}
|
||||
onImportClick={openImportLightbox}
|
||||
onFilterClick={toggleFilterBox}
|
||||
onForkClick={forkMap}
|
||||
canEditMap={canEditMap}
|
||||
filterBoxHtml={filterBoxHtml} />
|
||||
<DataVis />
|
||||
<TopicCard {...this.props} />
|
||||
<MapChat {...this.props} onOpen={onChatOpen} onClose={onChatClose} chatOpen={chatOpen} />
|
||||
<MapControls />
|
||||
<MapControls onClickZoomExtents={onZoomExtents}
|
||||
onClickZoomIn={onZoomIn}
|
||||
onClickZoomOut={onZoomOut} />
|
||||
<InfoAndHelp mapIsStarred={mapIsStarred}
|
||||
currentUser={currentUser}
|
||||
map={map}
|
||||
onInfoClick={toggleMapInfoBox}
|
||||
onMapStar={onMapStar}
|
||||
onMapUnstar={onMapUnstar}
|
||||
onHelpClick={openHelpLightbox}
|
||||
infoBoxHtml={infoBoxHtml} />
|
||||
</div>
|
||||
}
|
||||
|
|
|
@ -4,12 +4,6 @@ import Header from './Header'
|
|||
import MapperCard from './MapperCard'
|
||||
import MapCard from './MapCard'
|
||||
|
||||
// 220 wide + 16 padding on both sides
|
||||
const MAP_WIDTH = 252
|
||||
const MOBILE_VIEW_BREAKPOINT = 504
|
||||
const MOBILE_VIEW_PADDING = 40
|
||||
const MAX_COLUMNS = 4
|
||||
|
||||
class Maps extends Component {
|
||||
|
||||
static propTypes = {
|
||||
|
@ -23,37 +17,17 @@ class Maps extends Component {
|
|||
pending: PropTypes.bool,
|
||||
onStar: PropTypes.func,
|
||||
onRequest: PropTypes.func,
|
||||
onMapFollow: PropTypes.func
|
||||
onMapFollow: PropTypes.func,
|
||||
mapsWidth: PropTypes.number,
|
||||
mobile: PropTypes.bool
|
||||
}
|
||||
|
||||
static contextTypes = {
|
||||
location: PropTypes.object
|
||||
}
|
||||
|
||||
constructor(props) {
|
||||
super(props)
|
||||
this.state = { mapsWidth: 0 }
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
window && window.addEventListener('resize', this.resize)
|
||||
this.refs.maps && this.refs.maps.addEventListener('scroll', throttle(this.scroll, 500, { leading: true, trailing: false }))
|
||||
this.resize()
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
window && window.removeEventListener('resize', this.resize)
|
||||
}
|
||||
|
||||
resize = () => {
|
||||
const { maps, user, currentUser } = this.props
|
||||
if (!maps) return
|
||||
const numCards = maps.length + (user || currentUser ? 1 : 0)
|
||||
const mapSpaces = Math.floor(document.body.clientWidth / MAP_WIDTH)
|
||||
const mapsWidth = document.body.clientWidth <= MOBILE_VIEW_BREAKPOINT
|
||||
? document.body.clientWidth - MOBILE_VIEW_PADDING
|
||||
: Math.min(MAX_COLUMNS, Math.min(numCards, mapSpaces)) * MAP_WIDTH
|
||||
this.setState({ mapsWidth })
|
||||
this.maps && this.maps.addEventListener('scroll', throttle(this.scroll, 500, { leading: true, trailing: false }))
|
||||
}
|
||||
|
||||
scroll = () => {
|
||||
|
@ -65,15 +39,14 @@ class Maps extends Component {
|
|||
}
|
||||
|
||||
render = () => {
|
||||
const { maps, currentUser, juntoState, pending, section, user, onStar, onRequest, onMapFollow } = this.props
|
||||
const style = { width: this.state.mapsWidth + 'px' }
|
||||
const mobile = document && document.body.clientWidth <= MOBILE_VIEW_BREAKPOINT
|
||||
const { mobile, maps, mapsWidth, currentUser, juntoState, pending, section, user, onStar, onRequest, onMapFollow } = this.props
|
||||
const style = { width: mapsWidth + 'px' }
|
||||
|
||||
if (!maps) return null // do loading here instead
|
||||
|
||||
return (
|
||||
<div>
|
||||
<div id='exploreMaps' ref='maps'>
|
||||
<div id='exploreMaps' ref={x => this.maps = x}>
|
||||
<div style={ style }>
|
||||
{ user ? <MapperCard user={ user } /> : null }
|
||||
{ currentUser && !user && !(pending && maps.length === 0) ? <div className="map newMap"><a href="/maps/new"><div className="newMapImage"></div><span>Create new map...</span></a></div> : null }
|
||||
|
|
Loading…
Add table
Reference in a new issue