Skip to content

Commit

Permalink
Bug fixes and features in preperation for DM 2.0 beta (#163)
Browse files Browse the repository at this point in the history
Bug fixes and features in preparation for DM 2.0 beta
  • Loading branch information
NickLaiacona authored Feb 27, 2019
1 parent 332eaec commit 4171795
Show file tree
Hide file tree
Showing 23 changed files with 336 additions and 212 deletions.
8 changes: 7 additions & 1 deletion app/models/document.rb
Original file line number Diff line number Diff line change
Expand Up @@ -4,19 +4,25 @@ class Document < Linkable
belongs_to :project, touch: true
belongs_to :locked_by, class_name: 'User', optional: true
belongs_to :parent, polymorphic: true, optional: true
has_many :highlights, dependent: :destroy
has_many :highlights, dependent: :delete_all
has_many_attached :images

include PgSearch
include TreeNode

after_create :add_to_tree
before_destroy :remove_from_tree
# before_destroy :purge_images

MAX_IMAGE_SIZE = 10

pg_search_scope :search_for, against: %i(title search_text)

# TODO this won't be called by delete_all - need a better way to clean up images
# def purge_images
# self.images.each { |image| image.purge }
# end

# checks that all images validate, purges invalid images
def valid_images?
self.images.each { |image|
Expand Down
2 changes: 1 addition & 1 deletion app/models/document_folder.rb
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
class DocumentFolder < ApplicationRecord
belongs_to :project, touch: true
belongs_to :parent, polymorphic: true
belongs_to :parent, polymorphic: true, optional: true
has_many :documents, as: :parent, dependent: :destroy
has_many :document_folders, as: :parent, dependent: :destroy

Expand Down
1 change: 1 addition & 0 deletions app/models/highlight.rb
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ def to_obj
highlight_id: self.highlight_id,
document_id: self.document_id,
document_kind: self.document_kind,
document_title: self.document_title,
excerpt: self.excerpt,
color: self.color,
thumbnail_url: self.thumbnail_url
Expand Down
9 changes: 4 additions & 5 deletions app/models/project.rb
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
class Project < ApplicationRecord
belongs_to :owner, class_name: 'User', optional: true
has_many :documents, as: :parent, dependent: :destroy
has_many :document_folders, as: :parent, dependent: :destroy
has_many :user_project_permissions
has_many :documents, as: :parent, dependent: :delete_all
has_many :document_folders, as: :parent, dependent: :delete_all
has_many :user_project_permissions, dependent: :delete_all
has_many :users, through: :user_project_permissions

default_scope { order(updated_at: :desc) }
scope :is_public, -> { where(public: true) }

Expand Down Expand Up @@ -45,5 +45,4 @@ def migrate_to_position!
folder.migrate_to_position!
}
end

end
Binary file modified client/public/favicon.ico
Binary file not shown.
2 changes: 1 addition & 1 deletion client/public/index.html
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
homescreen on Android. See https://developers.google.com/web/fundamentals/engage-and-retain/web-app-manifest/
-->
<link rel="manifest" href="%PUBLIC_URL%/manifest.json">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico">
<link rel="shortcut icon" href="%PUBLIC_URL%/favicon.ico?v=2">
<!--
Notice the use of %PUBLIC_URL% in the tags above.
It will be replaced with the URL of the `public` folder during the build.
Expand Down
4 changes: 2 additions & 2 deletions client/public/manifest.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"short_name": "React App",
"name": "Create React App Sample",
"short_name": "DM",
"name": "Digital Mappa",
"icons": [
{
"src": "favicon.ico",
Expand Down
43 changes: 29 additions & 14 deletions client/src/CanvasResource.js
Original file line number Diff line number Diff line change
Expand Up @@ -140,7 +140,6 @@ class CanvasResource extends Component {
overlay.fabricCanvas().discardActiveObject();
}
});
overlay.fabricCanvas().on('mouse:out', this.clearFocusHighlightTimeout.bind(this));
overlay.fabricCanvas().on('mouse:down', this.canvasMouseDown.bind(this) );
overlay.fabricCanvas().on('mouse:move', this.canvasMouseMove.bind(this) );
overlay.fabricCanvas().on('mouse:up', this.canvasMouseUp.bind(this) );
Expand All @@ -156,6 +155,19 @@ class CanvasResource extends Component {
}
}
});

// rollover highlights
overlay.fabricCanvas().on('mouse:over', event => {
if (this.currentMode === 'pan' && event.target && event.target._highlightUid) {
window.showRollover(this.props.document_id, event.target._highlightUid);
}
});
overlay.fabricCanvas().on('mouse:out', function(event) {
if (this.currentMode === 'pan' && event.target && event.target._highlightUid) {
window.hideRollover(event.target._highlightUid);
}
}.bind(this));

// process paths created with pencil tool
overlay.fabricCanvas().on('path:created', event => {
if (event.path) {
Expand Down Expand Up @@ -209,19 +221,12 @@ class CanvasResource extends Component {
}
}

objectClick(event) {
if (this.currentMode === 'pan' && event.target && event.target._highlightUid) {
window.setFocusHighlight(this.props.document_id, event.target._highlightUid);
}
}

canvasMouseDown(event) {

if( this.currentMode === 'edit' || this.currentMode === 'pan' ) return;

this.isMouseDown = true;
this.pointerCoords = this.overlay.fabricCanvas().getPointer(event.e);
this.clearFocusHighlightTimeout();

switch(this.currentMode) {
case 'marker':
Expand Down Expand Up @@ -347,11 +352,6 @@ class CanvasResource extends Component {
this.newShape = null;
}

clearFocusHighlightTimeout() {
if (window.highlightFocusTimeout)
window.clearTimeout(window.highlightFocusTimeout);
}

renderHighlights(overlay, highlight_map) {
const jsonBlob = {objects: []};
for (const highlightUid in highlight_map) {
Expand All @@ -370,6 +370,7 @@ class CanvasResource extends Component {
object.dirty = true;
object.perPixelTargetFind = true;
object.selectable = true;

if (!this.props.writeEnabled) {
object.hoverCursor = 'default';
}
Expand Down Expand Up @@ -676,7 +677,7 @@ class CanvasResource extends Component {
}

render() {
const { document_id, content, image_thumbnail_urls, addTileSourceMode, image_urls, displayColorPickers, highlightColors, toggleCanvasColorPicker, setCanvasHighlightColor, writeEnabled, lockedByMe, globalCanvasDisplay } = this.props;
const { document_id, content, image_thumbnail_urls, addTileSourceMode, image_urls, highlightsHidden, displayColorPickers, highlightColors, toggleCanvasColorPicker, setCanvasHighlightColor, writeEnabled, lockedByMe, globalCanvasDisplay } = this.props;
const key = this.getInstanceKey();

this.highlight_map = this.props.highlight_map;
Expand All @@ -702,11 +703,24 @@ class CanvasResource extends Component {

let editable = ( writeEnabled && lockedByMe );
const mode = addTileSourceMode[document_id];
const highlightHidden = !editable && highlightsHidden[key]

if( !editable && this.currentMode !== 'pan' ) {
this.panClick();
}

// don't render highlights if they are hidden
if( this.overlay ) {
const canvas = this.overlay.fabricCanvas()
if( highlightHidden && !canvas.isEmpty() ) {
canvas.clear();
} else {
if( !highlightHidden && canvas.isEmpty() ) {
this.renderHighlights(this.overlay,this.highlight_map)
}
}
}

return (
<div style={{ display: 'flex', flexGrow: '1', padding: '10px' }}>
<div style={{ display: (mode || !globalCanvasDisplay) ? 'none' : 'flex', flexDirection: 'column', width: '100%' }}>
Expand Down Expand Up @@ -776,6 +790,7 @@ class CanvasResource extends Component {

const mapStateToProps = state => ({
highlightColors: state.canvasEditor.highlightColors,
highlightsHidden: state.canvasEditor.highlightsHidden,
displayColorPickers: state.canvasEditor.displayColorPickers,
addTileSourceMode: state.canvasEditor.addTileSourceMode,
imageURLs: state.canvasEditor.imageURLs,
Expand Down
24 changes: 23 additions & 1 deletion client/src/DocumentViewer.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,12 @@ import Paper from 'material-ui/Paper';
import TextField from 'material-ui/TextField';
import IconButton from 'material-ui/IconButton';
import Close from 'material-ui/svg-icons/navigation/close';
import Visibility from 'material-ui/svg-icons/action/visibility';
import VisibilityOff from 'material-ui/svg-icons/action/visibility-off';
import Description from 'material-ui/svg-icons/action/description';
import { grey100, grey800, grey900 } from 'material-ui/styles/colors';
import { updateDocument, closeDocument, moveDocumentWindow, layoutOptions } from './modules/documentGrid';
import { toggleHighlights } from './modules/canvasEditor'
import { closeDocumentTargets } from './modules/annotationViewer';
import TextResource from './TextResource';
import CanvasResource from './CanvasResource';
Expand Down Expand Up @@ -96,6 +99,17 @@ class DocumentViewer extends Component {
}, this.titleChangeDelayMs);
}

onToggleHighlights() {
const key = this.getInstanceKey()
const currentState = this.props.highlightsHidden[key] === true ? true : false
this.props.toggleHighlights( key, !currentState )
}

getInstanceKey() {
const { document_id, timeOpened } = this.props;
return `${document_id}-${timeOpened}`;
}

onCloseDocument() {
this.props.closeDocument(this.props.document_id)
this.props.closeDocumentTargets(this.props.document_id)
Expand All @@ -108,6 +122,7 @@ class DocumentViewer extends Component {
height: '20px'
};
const buttonStyle = Object.assign({ margin: '2px' }, iconStyle);
const highlightsHidden = this.props.highlightsHidden[this.getInstanceKey()]

return (
this.props.connectDragSource(
Expand All @@ -126,6 +141,11 @@ class DocumentViewer extends Component {
onChange={this.onChangeTitle}
disabled={!this.isEditable()}
/>
{ this.props.document_kind === 'canvas' && !this.isEditable() &&
<IconButton tooltip='Toggle highlights' onClick={this.onToggleHighlights.bind(this)} style={buttonStyle} iconStyle={iconStyle}>
{ highlightsHidden ? <VisibilityOff color='#FFF' /> : <Visibility color='#FFF' /> }
</IconButton>
}
<IconButton tooltip='Close document' onClick={this.onCloseDocument.bind(this)} style={buttonStyle} iconStyle={iconStyle}>
<Close color={this.props.document_kind === 'canvas' ? '#FFF' : '#000'} />
</IconButton>
Expand Down Expand Up @@ -205,13 +225,15 @@ const mapStateToProps = state => ({
openDocuments: state.documentGrid.openDocuments,
currentLayout: layoutOptions[state.documentGrid.currentLayout],
sidebarWidth: state.project.sidebarWidth,
highlightsHidden: state.canvasEditor.highlightsHidden
});

const mapDispatchToProps = dispatch => bindActionCreators({
updateDocument,
closeDocument,
moveDocumentWindow,
closeDocumentTargets
closeDocumentTargets,
toggleHighlights
}, dispatch);

export default connect(
Expand Down
37 changes: 25 additions & 12 deletions client/src/LinkInspectorPopup.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class LinkInspectorPopup extends Component {
this.state = {
titleBuffer: props.target.excerpt,
titleUpdateTimer: null,
titleHasFocus: false
titleHasFocus: false
}
}

Expand Down Expand Up @@ -69,7 +69,7 @@ class LinkInspectorPopup extends Component {
const titleBarID = `highlight-title-${this.props.target.uid}`

if( this.props.target.highlight_id ) {
if( this.state.titleHasFocus ) {
if( this.state.titleHasFocus && !this.props.rollover ) {
return (
<span>
<TextField
Expand Down Expand Up @@ -105,8 +105,12 @@ class LinkInspectorPopup extends Component {
}
}

getInnerID() {
return `${this.props.id}-inner`
}

render() {
const { target } = this.props;
const { target, writeEnabled, rollover } = this.props;

const titleBarColor = this.getTitleColor(target.color);

Expand All @@ -118,24 +122,33 @@ class LinkInspectorPopup extends Component {
height: '20px'
};

const linkInspectorVisible = (writeEnabled && !rollover) || (this.props.target.links_to && this.props.target.links_to.length > 0)
const linkInspectorProps = { ...this.props, writeEnabled: writeEnabled && !rollover }

return (
<Draggable handle='.links-popup-drag-handle' bounds='parent' disabled={this.state.titleHasFocus} >
<Paper zDepth={4} style={{ position: 'absolute', top: `${target.startPosition.y}px`, left: `${target.startPosition.x}px`, zIndex: (999 + this.props.popupIndex).toString()}}>
<Draggable handle='.links-popup-drag-handle' bounds='parent' disabled={this.state.titleHasFocus || this.props.rollover} >
<Paper
id={this.getInnerID()}
zDepth={4}
style={{ position: 'absolute', top: `${target.startPosition.y}px`, left: `${target.startPosition.x}px`, zIndex: (999 + this.props.popupIndex).toString()}}
>
<div style={{ display: 'flex', flexShrink: '0', backgroundColor: titleBarColor }}>
<Subheader style={{ flexGrow: '1', cursor: '-webkit-grab' }} className='links-popup-drag-handle' onMouseDown={this.props.onDragHandleMouseDown} >
<ModeComment style={linkIconStyle}/>
{ this.renderTitle(titleBarColor) }
</Subheader>
<IconButton
<IconButton
iconStyle={{width: '16px', height: '16px' }}
onClick={this.props.closeHandler}
>
<Close />
</IconButton>
>
{ !this.props.rollover && <Close /> }
</IconButton>
</div>
<div style={{flexGrow: 1 }}>
<LinkInspector {...this.props} />
</div>
{ linkInspectorVisible &&
<div style={{flexGrow: 1 }}>
<LinkInspector { ...linkInspectorProps } />
</div>
}
</Paper>
</Draggable>
)
Expand Down
1 change: 1 addition & 0 deletions client/src/LinkInspectorPopupLayer.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ export default class LinkInspectorPopupLayer extends Component {
onDragHandleMouseDown={() => {this.props.mouseDownHandler(target.document_id, target.highlight_id);}}
openDocumentIds={this.props.openDocumentIds}
writeEnabled={this.props.writeEnabled}
rollover={target.rollover}
/>
))}
</div>
Expand Down
4 changes: 2 additions & 2 deletions client/src/LinkableList.js
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,8 @@ class LinkableList extends Component {

let primaryText = item.document_title;
if (item.excerpt && item.excerpt.length > 0)
primaryText = <div><span style={{ background: item.color || 'yellow' }}>{item.excerpt}</span></div>;

primaryText = <div><span style={{ background: item.color || 'yellow' }}>{item.excerpt}</span> in <i>{item.document_title}</i></div>;
return (
<div key={itemKey}>
{inContents && writeEnabled &&
Expand Down
Loading

0 comments on commit 4171795

Please sign in to comment.