its coming along

This commit is contained in:
Connor Turland 2017-01-13 00:45:21 -05:00 committed by Devin Howard
parent 47d0faadf2
commit aa84ce812f
12 changed files with 334 additions and 414 deletions

View file

@ -213,50 +213,18 @@
padding: 0;
height: 48px;
}
.linkItem.contributor {
margin-left:40px;
z-index:1;
padding:17px 16px 17px 30px;
position: relative;
}
.contributor .contributorIcon {
position: absolute;
top: 8px;
left: 0;
border-radius: 16px;
}
.contributor:hover .contributorName {
display: block;
}
.contributorName {
display: none;
position: absolute;
background: black;
text-align: center;
color: white;
border-radius: 2px;
font-family: din-regular;
line-height: 15px;
font-size: 12px;
padding: 3px 5px 2px;
white-space: nowrap;
margin-top: 36px;
margin-left: -32px;
}
.contributor div:before {
content: '';
position: absolute;
top: 128%;
left: 13px;
margin-top: -30px;
width: 0;
height: 0;
border-bottom: 4px solid #000000;
border-left: 5px solid transparent;
border-right: 5px solid transparent;
.contributor {
.contributorIcon {
display: inline-block;
vertical-align: middle;
border-radius: 14px;
margin: 5px;
}
span {
font-family: 'din-regular', sans-serif;
font-size: 14px;
}
}
.linkItem.mapCount {
@ -497,15 +465,17 @@ cursor: pointer;
}
.CardOnGraph .metacodeImage {
cursor:move;
width:46px;
height:46px;
position:absolute;
left:-23px;
top:0;
background-size:46px 46px;
width:32px;
height:32px;
background-size:32px 32px;
background-position:0 0;
background-repeat:no-repeat;
display: inline-block;
vertical-align: middle;
margin: 5px;
}
.CardOnGraph .metacodeName {
display: inline-block;
}
#metacodeOptions {
@ -623,18 +593,15 @@ background-color: #E0E0E0;
z-index:100;
}
#embedlyLink {
display: none;
}
#embedlyLinkLoader {
margin: 0 auto;
width: 28px;
}
.CardOnGraph .attachments {
border-top: 1px solid #BDBDBD;
width:100%;
height:47px;
position: relative;
}
.attachments a {
@ -752,7 +719,6 @@ font-family: 'din-regular', helvetica, sans-serif;
-moz-border-radius-bottomright: 8px;
-webkit-border-bottom-right-radius: 8px;
border-bottom-right-radius: 8px;
display: none;
margin: 8px;
}

View file

@ -181,72 +181,4 @@
<div class="clearfloat"></div>
</div>
</script>
<script type="text/template" id="topicCardTemplate">
<div class="CardOnGraph {{hasAttachment}}" id="topic_{{id}}">
<span class="title">
<div class="titleWrapper" id="titleActivator">
<span class="best_in_place best_in_place_name"
data-bip-url="/topics/{{id}}"
data-bip-object="topic"
data-bip-attribute="name"
data-bip-activator="#titleActivator"
data-bip-value="{{name}}"
data-bip-type="textarea"
>
{{name}}
</span>
</div>
</span>
<div class="links">
<div class="linkItem icon">
<div class="metacodeTitle {{metacode_class}}">
{{metacode}}
<div class="expandMetacodeSelect"></div>
</div>
<div class="metacodeImage" style="background-image:url({{imgsrc}});" title="click and drag to move card"></div>
<div class="metacodeSelect">{{{metacode_select}}}</div>
</div>
<div class="linkItem contributor">
<a href="/explore/mapper/{{userid}}" target="_blank"><img src="<%= asset_path('user.png') %>" class="contributorIcon" width="32" height="32" /></a>
<div class="contributorName">{{username}}</div>
</div>
<div class="linkItem mapCount">
<div class="mapCountIcon"></div>
{{map_count}}
<div class ="hoverTip">Click to see which maps topic appears on</div>
<div class="tip"><ul>{{{inmaps}}}</ul></div>
</div>
<a href="/topics/{{id}}" target="_blank" class="linkItem synapseCount">
<div class="synapseCountIcon"></div>
{{synapse_count}}
<div class="tip">Click to see this topics synapses</div>
</a>
<div class="linkItem mapPerm {{mk_permission}}" title="{{permission}}"></div>
<div class="clearfloat"></div>
</div>
<div class="scroll">
<div class="desc">
<span class="best_in_place best_in_place_desc"
data-bip-url="/topics/{{id}}"
data-bip-object="topic"
data-bip-nil="{{desc_nil}}"
data-bip-attribute="desc"
data-bip-type="textarea"
data-bip-value="{{desc_markdown}}"
>
{{{desc_html}}}
</span>
<div class="clearfloat"></div>
</div>
</div>
<div class="embeds">
{{{embeds}}}
</div>
<div class="attachments {{attachmentsHidden}}">
{{{attachments}}}
</div>
<div class="clearfloat"></div>
</div>
</script>
</div>

View file

@ -4,7 +4,7 @@ try { Backbone.$ = window.$ } catch (err) {}
import Active from '../Active'
import Filter from '../Filter'
import TopicCard from '../TopicCard'
import TopicCard from '../Views/TopicCard'
import Visualize from '../Visualize'
import DataModel from './index'

View file

@ -18,7 +18,7 @@ import Settings from './Settings'
import Synapse from './Synapse'
import SynapseCard from './SynapseCard'
import Topic from './Topic'
import TopicCard from './TopicCard'
import TopicCard from './Views/TopicCard'
import Util from './Util'
import Visualize from './Visualize'
import clipboard from 'clipboard-js'

View file

@ -16,7 +16,7 @@ import Realtime from '../Realtime'
import Router from '../Router'
import Selected from '../Selected'
import SynapseCard from '../SynapseCard'
import TopicCard from '../TopicCard'
import TopicCard from '../Views/TopicCard'
import Visualize from '../Visualize'
import CheatSheet from './CheatSheet'

View file

@ -14,7 +14,7 @@ import Router from './Router'
import Selected from './Selected'
import Settings from './Settings'
import SynapseCard from './SynapseCard'
import TopicCard from './TopicCard'
import TopicCard from './Views/TopicCard'
import Util from './Util'
import Visualize from './Visualize'

View file

@ -49,6 +49,7 @@ const ChatView = {
$('#' + ChatView.domId).hide()
},
render: () => {
return
if (!Active.Map) return
const self = ChatView
self.mapChat = ReactDOM.render(React.createElement(MapChat, {

View file

@ -0,0 +1,61 @@
/* global $ */
import React from 'react'
import ReactDOM from 'react-dom'
import Active from '../Active'
import DataModel from '../DataModel'
import GlobalUI from '../GlobalUI'
import Mapper from '../Mapper'
import Router from '../Router'
import Visualize from '../Visualize'
import ReactTopicCard from '../../components/TopicCard'
const TopicCard = {
openTopicCard: null, // stores the topic that's currently open
init: function() {
// initialize topic card draggability and resizability
$('.showcard').draggable({
handle: '.metacodeImage',
stop: function() {
$(this).height('auto')
}
})
},
populateShowCard: function(topic) {
var self = TopicCard
const topicCardObj = {
topic: topic,
ActiveMapper: Active.Mapper,
removeLink: () => {
topic.save({
link: null
},{success: topic => self.populateShowCard(topic)})
},
addLink: link => {
topic.save({link},{success: topic => self.populateShowCard(topic)})
}
}
ReactDOM.render(
React.createElement(ReactTopicCard, topicCardObj),
document.getElementById('showcard')
)
},
showCard: function(node, opts) {
var self = TopicCard
if (!opts) opts = {}
var topic = node.getData('topic')
self.openTopicCard = topic
// populate the card that's about to show with the right topics data
self.populateShowCard(topic)
return $('.showcard').fadeIn('fast', () => opts.complete && opts.complete())
},
hideCard: function() {
var self = TopicCard
$('.showcard').fadeOut('fast')
self.openTopicCard = null
}
}
export default TopicCard

View file

@ -4,18 +4,21 @@ import ExploreMaps from './ExploreMaps'
import ChatView from './ChatView'
import VideoView from './VideoView'
import Room from './Room'
import TopicCard from './TopicCard'
import { JUNTO_UPDATED } from '../Realtime/events'
const Views = {
init: (serverData) => {
$(document).on(JUNTO_UPDATED, () => ExploreMaps.render())
ChatView.init([serverData['sounds/MM_sounds.mp3'], serverData['sounds/MM_sounds.ogg']])
},
ExploreMaps,
ChatView,
VideoView,
Room
Room,
TopicCard
}
export { ExploreMaps, ChatView, VideoView, Room }
export { ExploreMaps, ChatView, VideoView, Room, TopicCard }
export default Views

View file

@ -9,7 +9,7 @@ import DataModel from './DataModel'
import JIT from './JIT'
import Loading from './Loading'
import Router from './Router'
import TopicCard from './TopicCard'
import TopicCard from './Views/TopicCard'
const Visualize = {
mGraph: null, // a reference to the graph object.

View file

@ -29,7 +29,6 @@ import Settings from './Settings'
import Synapse from './Synapse'
import SynapseCard from './SynapseCard'
import Topic from './Topic'
import TopicCard from './TopicCard'
import Util from './Util'
import Views from './Views'
import Visualize from './Visualize'
@ -71,7 +70,6 @@ Metamaps.Settings = Settings
Metamaps.Synapse = Synapse
Metamaps.SynapseCard = SynapseCard
Metamaps.Topic = Topic
Metamaps.TopicCard = TopicCard
Metamaps.Util = Util
Metamaps.Views = Views
Metamaps.Visualize = Visualize

View file

@ -1,165 +1,66 @@
/* global $, CanvasLoader, Countable, Hogan, embedly */
import React, { PropTypes, Component } from 'react'
import Active from './Active'
import DataModel from './DataModel'
import GlobalUI from './GlobalUI'
import Mapper from './Mapper'
import Router from './Router'
import Util from './Util'
import Visualize from './Visualize'
import Util from '../Metamaps/Util'
const TopicCard = {
openTopicCard: null, // stores the topic that's currently open
authorizedToEdit: false, // stores boolean for edit permission for open topic card
RAILS_ENV: undefined,
init: function(serverData) {
var self = TopicCard
/*
if (serverData.RAILS_ENV) {
self.RAILS_ENV = serverData.RAILS_ENV
TopicCard.bindShowCardListeners(topic)
do globalui notify for invalid link?
*/
var funcs = {
buildObject: function(topic, ActiveMapper) {
var nodeValues = {}
var authorized = topic.authorizeToEdit(ActiveMapper)
var inmapsAr = topic.get('inmaps') || []
var inmapsLinks = topic.get('inmapsLinks') || []
nodeValues.inmaps = ''
if (inmapsAr.length < 6) {
for (let i = 0; i < inmapsAr.length; i++) {
const url = '/maps/' + inmapsLinks[i]
nodeValues.inmaps += '<li><a href="' + url + '">' + inmapsAr[i] + '</a></li>'
}
} else {
console.error('RAILS_ENV is not defined! See TopicCard.js init function.')
for (let i = 0; i < 5; i++) {
const url = '/maps/' + inmapsLinks[i]
nodeValues.inmaps += '<li><a href="' + url + '">' + inmapsAr[i] + '</a></li>'
}
// initialize best_in_place editing
$('.authenticated div.permission.canEdit .best_in_place').best_in_place()
TopicCard.generateShowcardHTML = Hogan.compile($('#topicCardTemplate').html())
// initialize topic card draggability and resizability
$('.showcard').draggable({
handle: '.metacodeImage',
stop: function() {
$(this).height('auto')
const extra = inmapsAr.length - 5
nodeValues.inmaps += '<li><span class="showMore">See ' + extra + ' more...</span></li>'
for (let i = 5; i < inmapsAr.length; i++) {
const url = '/maps/' + inmapsLinks[i]
nodeValues.inmaps += '<li class="hideExtra extraText"><a href="' + url + '">' + inmapsAr[i] + '</a></li>'
}
})
embedly('on', 'card.rendered', self.embedlyCardRendered)
},
/**
* Will open the Topic Card for the node that it's passed
* @param {$jit.Graph.Node} node
*/
showCard: function(node, opts) {
var self = TopicCard
if (!opts) opts = {}
var topic = node.getData('topic')
self.openTopicCard = topic
self.authorizedToEdit = topic.authorizeToEdit(Active.Mapper)
// populate the card that's about to show with the right topics data
self.populateShowCard(topic)
return $('.showcard').fadeIn('fast', function() {
if (opts.complete) {
opts.complete()
}
})
},
hideCard: function() {
var self = TopicCard
$('.showcard').fadeOut('fast')
self.openTopicCard = null
self.authorizedToEdit = false
},
embedlyCardRendered: function(iframe) {
$('#embedlyLinkLoader').hide()
// means that the embedly call returned 404 not found
if ($('#embedlyLink')[0]) {
$('#embedlyLink').css('display', 'block').fadeIn('fast')
$('.embeds').addClass('nonEmbedlyLink')
}
$('.CardOnGraph').addClass('hasAttachment')
},
showLinkRemover: function() {
if (TopicCard.authorizedToEdit && $('#linkremove').length === 0) {
$('.embeds').append('<div id="linkremove"></div>')
$('#linkremove').click(TopicCard.removeLink)
}
},
removeLink: function() {
var self = TopicCard
self.openTopicCard.save({
link: null
})
$('.embeds').empty().removeClass('nonEmbedlyLink')
$('#addLinkInput input').val('')
$('.attachments').removeClass('hidden')
$('.CardOnGraph').removeClass('hasAttachment')
},
showLinkLoader: function() {
var loader = new CanvasLoader('embedlyLinkLoader')
loader.setColor('#4fb5c0') // default is '#000000'
loader.setDiameter(28) // default is 40
loader.setDensity(41) // default is 40
loader.setRange(0.9) // default is 1.3
loader.show() // Hidden by default
},
showLink: function(topic) {
var e = embedly('card', document.getElementById('embedlyLink'))
if (!e && TopicCard.RAILS_ENV !== 'development') {
TopicCard.handleInvalidLink()
} else if (!e) {
$('#embedlyLink').attr('target', '_blank').html(topic.get('link')).show()
$('#embedlyLinkLoader').hide()
}
nodeValues.permission = topic.get('permission')
nodeValues.mk_permission = topic.get('permission').substring(0, 2)
nodeValues.map_count = topic.get('map_count').toString()
nodeValues.synapse_count = topic.get('synapse_count').toString()
nodeValues.id = topic.isNew() ? topic.cid : topic.id
nodeValues.metacode = topic.getMetacode().get('name')
nodeValues.metacode_class = 'mbg' + topic.get('metacode_id')
nodeValues.imgsrc = topic.getMetacode().get('icon')
nodeValues.name = topic.get('name')
nodeValues.userid = topic.get('user_id')
nodeValues.username = topic.get('user_name')
nodeValues.userimage = topic.get('user_image')
nodeValues.date = topic.getDate()
// the code for this is stored in /views/main/_metacodeOptions.html.erb
nodeValues.metacode_select = $('#metacodeOptions').html()
nodeValues.desc_nil = 'Click to add description...'
nodeValues.desc_markdown = (topic.get('desc') === '' && authorized)
? nodeValues.desc_nil
: topic.get('desc')
nodeValues.desc_html = Util.mdToHTML(nodeValues.desc_markdown)
return nodeValues
},
bindShowCardListeners: function(topic) {
var self = TopicCard
var showCard = document.getElementById('showcard')
var authorized = self.authorizedToEdit
// get mapper image
var setMapperImage = function(mapper) {
$('.contributorIcon').attr('src', mapper.get('image'))
}
Mapper.get(topic.get('user_id'), setMapperImage)
// starting embed.ly
var resetFunc = function() {
$('#addLinkInput input').val('')
$('#addLinkInput input').focus()
}
var inputEmbedFunc = function(event) {
var element = this
setTimeout(function() {
var text = $(element).val()
if (event.type === 'paste' || (event.type === 'keyup' && event.which === 13)) {
// TODO evaluate converting this to '//' no matter what (infer protocol)
if (text.slice(0, 7) !== 'http://' &&
text.slice(0, 8) !== 'https://' &&
text.slice(0, 2) !== '//') {
text = '//' + text
}
topic.save({
link: text
})
var embedlyEl = $('<a/>', {
id: 'embedlyLink',
'data-card-description': '0',
href: text
}).html(text)
$('.attachments').addClass('hidden')
$('.embeds').append(embedlyEl)
$('.embeds').append('<div id="embedlyLinkLoader"></div>')
self.showLinkLoader()
self.showLink(topic)
}
}, 100)
}
$('#addLinkReset').click(resetFunc)
$('#addLinkInput input').bind('paste keyup', inputEmbedFunc)
// initialize the link card, if there is a link
if (topic.get('link') && topic.get('link') !== '') {
self.showLinkLoader()
self.showLink(topic)
self.showLinkRemover()
}
var selectingMetacode = false
// attach the listener that shows the metacode title when you hover over the image
@ -302,7 +203,6 @@ const TopicCard = {
})
$('.showcard .mapPerm').removeClass('co pu pr minimize').addClass(permission.substring(0, 2))
$('.showcard .permissionSelect').remove()
event.stopPropagation()
}
var openPermissionSelect = function(event) {
@ -336,18 +236,12 @@ const TopicCard = {
$('.links .mapCount').unbind().click(function(event) {
$('.mapCount .tip').toggle()
$('.showcard .hoverTip').toggleClass('hide')
event.stopPropagation()
})
$('.mapCount .tip').unbind().click(function(event) {
event.stopPropagation()
})
$('.showcard').unbind('.hideTip').bind('click.hideTip', function() {
$('.mapCount .tip').hide()
$('.showcard .hoverTip').removeClass('hide')
})
$('.mapCount .tip li a').click(Router.intercept)
var originalText = $('.showMore').html()
$('.mapCount .tip .showMore').unbind().toggle(
function(event) {
@ -358,117 +252,182 @@ const TopicCard = {
$('.extraText').toggleClass('hideExtra')
$('.showMore').html(originalText)
})
}
}
$('.mapCount .tip showMore').unbind().click(function(event) {
event.stopPropagation()
class ReactTopicCard extends Component {
constructor(props) {
super(props)
this.state = {
nameEdit: '',
descEdit: '',
linkEdit: '',
embedlyLinkError: false,
embedlyLinkStarted: false,
embedlyLinkLoaded: false
}
}
componentDidMount = () => {
const { topic } = this.props
embedly('on', 'card.rendered', this.embedlyCardRendered)
topic.get('link') && topic.get('link') !== '' && this.loadLink()
}
componentWillUnmount = () => {
embedly('off')
}
componentDidUpdate = () => {
const { topic } = this.props
const { embedlyLinkStarted } = this.state
!embedlyLinkStarted && topic.get('link') && topic.get('link') !== '' && this.loadLink()
}
embedlyCardRendered = (iframe, test) => {
this.setState({embedlyLinkLoaded: true, embedlyLinkError: false})
}
resetLinkInput = () => {
this.setState({linkEdit: ''})
this.linkInput.focus()
}
onLinkChangeHandler = e => {
this.setState({linkEdit: e.target.value})
}
onLinkKeyUpHandler = e => {
const { addLink } = this.props
const { linkEdit } = this.state
let finalLink
const ENTER_KEY = 13
if (e.which === ENTER_KEY) {
// TODO evaluate converting this to '//' no matter what (infer protocol)
if (linkEdit.slice(0, 7) !== 'http://' &&
linkEdit.slice(0, 8) !== 'https://' &&
linkEdit.slice(0, 2) !== '//') {
finalLink = '//' + linkEdit
}
this.setState({linkEdit: ''})
addLink(finalLink)
}
}
loadLink = () => {
this.setState({embedlyLinkStarted: true})
var e = embedly('card', document.getElementById('embedlyLink'))
if (e.type === 'error') this.setState({embedlyLinkError: true})
}
removeLink = () => {
const { removeLink } = this.props
this.setState({
embedlyLinkStarted: false,
embedlyLinkLoaded: false,
embedlyLinkError: false
})
},
handleInvalidLink: function() {
var self = TopicCard
self.removeLink()
GlobalUI.notifyUser('Invalid link')
},
populateShowCard: function(topic) {
var self = TopicCard
var showCard = document.getElementById('showcard')
$(showCard).find('.permission').remove()
var topicForTemplate = self.buildObject(topic)
var html = self.generateShowcardHTML.render(topicForTemplate)
if (topic.authorizeToEdit(Active.Mapper)) {
let perm = document.createElement('div')
var string = 'permission canEdit'
if (topic.authorizePermissionChange(Active.Mapper)) string += ' yourTopic'
perm.className = string
perm.innerHTML = html
showCard.appendChild(perm)
} else {
let perm = document.createElement('div')
perm.className = 'permission cannotEdit'
perm.innerHTML = html
showCard.appendChild(perm)
removeLink()
}
TopicCard.bindShowCardListeners(topic)
},
generateShowcardHTML: null, // will be initialized into a Hogan template within init function
// generateShowcardHTML
buildObject: function(topic) {
var nodeValues = {}
render = () => {
const { topic, ActiveMapper, removeLink } = this.props
const { linkEdit, embedlyLinkLoaded, embedlyLinkStarted, embedlyLinkError } = this.state
const values = funcs.buildObject(topic, ActiveMapper)
var authorizedToEdit = topic.authorizeToEdit(ActiveMapper)
let classname = 'permission'
if (authorizedToEdit) classname += ' canEdit'
else classname += ' cannotEdit'
if (topic.authorizePermissionChange(ActiveMapper)) classname += ' yourTopic'
const hasAttachment = topic.get('link') && topic.get('link') !== ''
var authorized = topic.authorizeToEdit(Active.Mapper)
if (!authorized) {
} else {
}
nodeValues.attachmentsHidden = ''
if (topic.get('link') && topic.get('link') !== '') {
nodeValues.embeds = '<a href="' + topic.get('link') + '" id="embedlyLink" target="_blank" data-card-description="0">'
nodeValues.embeds += topic.get('link')
nodeValues.embeds += '</a><div id="embedlyLinkLoader"></div>'
nodeValues.attachmentsHidden = 'hidden'
nodeValues.hasAttachment = 'hasAttachment'
} else {
nodeValues.embeds = ''
nodeValues.hasAttachment = ''
}
if (authorized) {
nodeValues.attachments = '<div class="addLink"><div id="addLinkIcon"></div>'
nodeValues.attachments += '<div id="addLinkInput"><input placeholder="Enter or paste a link"></input>'
nodeValues.attachments += '<div id="addLinkReset"></div></div></div>'
} else {
nodeValues.attachmentsHidden = 'hidden'
nodeValues.attachments = ''
}
var inmapsAr = topic.get('inmaps') || []
var inmapsLinks = topic.get('inmapsLinks') || []
nodeValues.inmaps = ''
if (inmapsAr.length < 6) {
for (let i = 0; i < inmapsAr.length; i++) {
const url = '/maps/' + inmapsLinks[i]
nodeValues.inmaps += '<li><a href="' + url + '">' + inmapsAr[i] + '</a></li>'
}
} else {
for (let i = 0; i < 5; i++) {
const url = '/maps/' + inmapsLinks[i]
nodeValues.inmaps += '<li><a href="' + url + '">' + inmapsAr[i] + '</a></li>'
}
const extra = inmapsAr.length - 5
nodeValues.inmaps += '<li><span class="showMore">See ' + extra + ' more...</span></li>'
for (let i = 5; i < inmapsAr.length; i++) {
const url = '/maps/' + inmapsLinks[i]
nodeValues.inmaps += '<li class="hideExtra extraText"><a href="' + url + '">' + inmapsAr[i] + '</a></li>'
}
}
nodeValues.permission = topic.get('permission')
nodeValues.mk_permission = topic.get('permission').substring(0, 2)
nodeValues.map_count = topic.get('map_count').toString()
nodeValues.synapse_count = topic.get('synapse_count').toString()
nodeValues.id = topic.isNew() ? topic.cid : topic.id
nodeValues.metacode = topic.getMetacode().get('name')
nodeValues.metacode_class = 'mbg' + topic.get('metacode_id')
nodeValues.imgsrc = topic.getMetacode().get('icon')
nodeValues.name = topic.get('name')
nodeValues.userid = topic.get('user_id')
nodeValues.username = topic.get('user_name')
nodeValues.date = topic.getDate()
// the code for this is stored in /views/main/_metacodeOptions.html.erb
nodeValues.metacode_select = $('#metacodeOptions').html()
nodeValues.desc_nil = 'Click to add description...'
nodeValues.desc_markdown = (topic.get('desc') === '' && authorized)
? nodeValues.desc_nil
: topic.get('desc')
nodeValues.desc_html = Util.mdToHTML(nodeValues.desc_markdown)
return nodeValues
return (
<div className={classname}>
<div className={`CardOnGraph ${hasAttachment ? 'hasAttachment' : ''}`} id={`topic_${values.id}`}>
<div className="metacodeImage" style={{backgroundImage: `url(${values.imgsrc})`}}></div>
<span className="metacodeName">{values.metacode}</span>
<span className="title">
<div className="titleWrapper" id="titleActivator">
<span className="best_in_place best_in_place_name">
{values.name}
</span>
</div>
</span>
<div className="scroll">
<div className="desc">
<span className="best_in_place best_in_place_desc"
dangerouslySetInnerHTML={{__html: values.desc_html}}
>
</span>
<div className="clearfloat"></div>
</div>
</div>
{hasAttachment && <div className={`embeds ${embedlyLinkLoaded ? '' : 'nonEmbedlyLink'}`}>
<a href={topic.get('link')} id="embedlyLink" target="_blank" data-card-description="0">
{topic.get('link')}
</a>
{embedlyLinkStarted && !embedlyLinkLoaded && !embedlyLinkError && <div id="embedlyLinkLoader">loading...</div>}
{authorizedToEdit && <div id="linkremove" onClick={this.removeLink}></div>}
</div>}
{authorizedToEdit && !hasAttachment && <div className='attachments'>
<div className="addLink">
<div id="addLinkIcon"></div>
<div id="addLinkInput">
<input ref={input => this.linkInput = input}
placeholder="Enter or paste a link"
value={linkEdit}
onChange={this.onLinkChangeHandler}
onKeyUp={this.onLinkKeyUpHandler}></input>
{linkEdit && <div id="addLinkReset"></div>}
</div>
</div>
</div>}
<div className='contributor'>
<img src={values.userimage} className="contributorIcon" width="28" height="28" />
<span>{values.username}</span>
</div>
<div className="clearfloat"></div>
</div>
</div>)
}
}
export default TopicCard
ReactTopicCard.propTypes = {
topic: PropTypes.object,
ActiveMapper: PropTypes.object,
removeLink: PropTypes.func,
addLink: PropTypes.func
}
export default ReactTopicCard
/*
<div className="links">
<div className="linkItem icon">
<div className={`metacodeTitle ${values.metacode_class}`}>
{values.metacode}
<div className="expandMetacodeSelect"></div>
</div>
<div className="metacodeImage" style={{backgroundImage: `url(${values.imgsrc})`}} title="click and drag to move card"></div>
<div className="metacodeSelect">{values.metacode_select}</div>
</div>
<div className="linkItem contributor">
<a href={`/explore/mapper/${values.userid}`} target="_blank"><img src={emptyAvatar} className="contributorIcon" width="32" height="32" /></a>
<div className="contributorName">{values.username}</div>
</div>
<div className="linkItem mapCount">
<div className="mapCountIcon"></div>
{values.map_count}
<div className ="hoverTip">Click to see which maps topic appears on</div>
<div className="tip"><ul>{values.inmaps}</ul></div>
</div>
<a href={`/topics/${values.id}`} target="_blank" className="linkItem synapseCount">
<div className="synapseCountIcon"></div>
{values.synapse_count}
<div className="tip">Click to see this topics synapses</div>
</a>
<div className={`linkItem mapPerm ${values.mk_permission}`} title={values.permission}></div>
<div className="clearfloat"></div>
</div>
*/