client/home: show post notes (read-only)
This commit is contained in:
parent
53fd6fb29b
commit
9b0c2012a7
4 changed files with 114 additions and 0 deletions
|
@ -32,3 +32,8 @@ $new-tag-text-color = black
|
|||
$default-tag-category-background-color = $active-tab-background-color
|
||||
$duplicate-tag-background-color = #FDC
|
||||
$duplicate-tag-text-color = black
|
||||
$note-overlay-background-color = rgba(255, 255, 255, 0.3)
|
||||
$note-overlay-border-color = rgba(0, 0, 0, 0.3)
|
||||
$note-text-background-color = lemonchiffon
|
||||
$note-text-border-color = black
|
||||
$note-text-text-color = black
|
||||
|
|
|
@ -27,3 +27,27 @@
|
|||
bottom: 0
|
||||
width: 100%
|
||||
height: 100%
|
||||
|
||||
.notes
|
||||
stroke-width: 1px
|
||||
polygon
|
||||
fill: $note-overlay-background-color
|
||||
stroke: $note-overlay-border-color
|
||||
|
||||
.note-text
|
||||
position: absolute
|
||||
max-width: 22.5em
|
||||
margin-top: -0.5em
|
||||
display: none
|
||||
|
||||
&>.wrapper
|
||||
background: $note-text-background-color
|
||||
padding: 0.5em
|
||||
border: 1px solid $note-text-border-color
|
||||
color: $note-text-text-color
|
||||
margin-top: 1em
|
||||
|
||||
p:last-of-type
|
||||
margin-bottom: 0
|
||||
p:first-of-type
|
||||
margin-top: 0
|
||||
|
|
79
client/js/controls/post_notes_overlay_control.js
Normal file
79
client/js/controls/post_notes_overlay_control.js
Normal file
|
@ -0,0 +1,79 @@
|
|||
'use strict';
|
||||
|
||||
const views = require('../util/views.js');
|
||||
const misc = require('../util/misc.js');
|
||||
const svgNS = 'http://www.w3.org/2000/svg';
|
||||
|
||||
class PostNotesOverlayControl {
|
||||
constructor(postOverlayNode, post) {
|
||||
this._post = post;
|
||||
this._postOverlayNode = postOverlayNode;
|
||||
this._install();
|
||||
}
|
||||
|
||||
_evtMouseEnter(e) {
|
||||
const bodyRect = document.body.getBoundingClientRect();
|
||||
const svgRect = this._svgNode.getBoundingClientRect();
|
||||
const polygonRect = e.target.getBBox();
|
||||
this._textNode.querySelector('.wrapper').innerHTML
|
||||
= misc.formatMarkdown(e.target.getAttribute('data-text'));
|
||||
this._textNode.style.left = (
|
||||
svgRect.left + svgRect.width * polygonRect.x) + 'px';
|
||||
this._textNode.style.top = (
|
||||
svgRect.top + svgRect.height * (
|
||||
polygonRect.y + polygonRect.height)) + 'px';
|
||||
this._textNode.style.display = 'block';
|
||||
}
|
||||
|
||||
_evtMouseLeave(e) {
|
||||
const newElement = e.relatedTarget;
|
||||
if (newElement === this._svgNode ||
|
||||
(!this._svgNode.contains(newElement)
|
||||
&& !this._textNode.contains(newElement)
|
||||
&& newElement !== this._textNode)) {
|
||||
this._textNode.style.display = 'none';
|
||||
}
|
||||
}
|
||||
|
||||
_install() {
|
||||
this._svgNode = document.createElementNS(svgNS, 'svg');
|
||||
this._svgNode.classList.add('notes');
|
||||
this._svgNode.setAttribute('preserveAspectRatio', 'none');
|
||||
this._svgNode.setAttribute('viewBox', '0 0 1 1');
|
||||
for (let note of this._post.notes) {
|
||||
const polygonNode = document.createElementNS(svgNS, 'polygon');
|
||||
polygonNode.setAttribute(
|
||||
'vector-effect', 'non-scaling-stroke');
|
||||
polygonNode.setAttribute(
|
||||
'stroke-alignment', 'inside');
|
||||
polygonNode.setAttribute(
|
||||
'points', note.polygon.map(point => point.join(',')).join(' '));
|
||||
polygonNode.setAttribute('data-text', note.text);
|
||||
polygonNode.addEventListener(
|
||||
'mouseenter', e => this._evtMouseEnter(e));
|
||||
polygonNode.addEventListener(
|
||||
'mouseleave', e => this._evtMouseLeave(e));
|
||||
this._svgNode.appendChild(polygonNode);
|
||||
}
|
||||
this._postOverlayNode.appendChild(this._svgNode);
|
||||
|
||||
const wrapperNode = document.createElement('div');
|
||||
wrapperNode.classList.add('wrapper');
|
||||
this._textNode = document.createElement('div');
|
||||
this._textNode.classList.add('note-text');
|
||||
this._textNode.appendChild(wrapperNode);
|
||||
this._textNode.addEventListener(
|
||||
'mouseleave', e => this._evtMouseLeave(e));
|
||||
document.body.appendChild(this._textNode);
|
||||
|
||||
views.monitorNodeRemoval(
|
||||
this._postOverlayNode, () => { this._uninstall(); });
|
||||
}
|
||||
|
||||
_uninstall() {
|
||||
this._postOverlayNode.removeChild(this._svgNode);
|
||||
document.body.removeChild(this._textNode);
|
||||
}
|
||||
};
|
||||
|
||||
module.exports = PostNotesOverlayControl;
|
|
@ -5,6 +5,8 @@ const config = require('../config.js');
|
|||
const misc = require('../util/misc.js');
|
||||
const views = require('../util/views.js');
|
||||
const PostContentControl = require('../controls/post_content_control.js');
|
||||
const PostNotesOverlayControl
|
||||
= require('../controls/post_notes_overlay_control.js');
|
||||
const TagAutoCompleteControl =
|
||||
require('../controls/tag_auto_complete_control.js');
|
||||
|
||||
|
@ -49,6 +51,10 @@ class HomeView {
|
|||
window.innerHeight * 0.7,
|
||||
];
|
||||
});
|
||||
|
||||
new PostNotesOverlayControl(
|
||||
postContainerNode.querySelector('.post-overlay'),
|
||||
ctx.featuredPost);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue