const React = require('react'); const { connect } = require('react-redux'); const shared = require('lib/components/shared/side-menu-shared.js'); const { Synchronizer } = require('lib/synchronizer.js'); const { BaseModel } = require('lib/base-model.js'); const { Folder } = require('lib/models/folder.js'); const { Note } = require('lib/models/note.js'); const { Tag } = require('lib/models/tag.js'); const { _ } = require('lib/locale.js'); const { themeStyle } = require('../theme.js'); const { bridge } = require('electron').remote.require('./bridge'); const Menu = bridge().Menu; const MenuItem = bridge().MenuItem; class SideBarComponent extends React.Component { style() { const theme = themeStyle(this.props.theme); const itemHeight = 25; let style = { root: { backgroundColor: theme.backgroundColor2, }, listItem: { height: itemHeight, fontFamily: theme.fontFamily, fontSize: theme.fontSize, textDecoration: 'none', boxSizing: 'border-box', color: theme.color2, paddingLeft: 14, display: 'flex', alignItems: 'center', cursor: 'default', opacity: 0.8, }, listItemSelected: { backgroundColor: theme.selectedColor2, }, conflictFolder: { color: theme.colorError2, fontWeight: 'bold', }, header: { height: itemHeight * 1.8, fontFamily: theme.fontFamily, fontSize: theme.fontSize * 1.3, textDecoration: 'none', boxSizing: 'border-box', color: theme.color2, paddingLeft: 8, display: 'flex', alignItems: 'center', }, button: { padding: 6, fontFamily: theme.fontFamily, fontSize: theme.fontSize, textDecoration: 'none', boxSizing: 'border-box', color: theme.color2, display: 'flex', alignItems: 'center', justifyContent: 'center', border: "1px solid rgba(255,255,255,0.2)", marginTop: 10, marginLeft: 5, marginRight: 5, cursor: 'default', }, syncReport: { fontFamily: theme.fontFamily, fontSize: Math.round(theme.fontSize * .9), color: theme.color2, opacity: .5, display: 'flex', alignItems: 'left', justifyContent: 'top', flexDirection: 'column', marginTop: 10, marginLeft: 5, marginRight: 5, minHeight: 70, }, }; return style; } itemContextMenu(event) { const itemId = event.target.getAttribute('data-id'); if (itemId === Folder.conflictFolderId()) return; const itemType = Number(event.target.getAttribute('data-type')); if (!itemId || !itemType) throw new Error('No data on element'); let deleteMessage = ''; if (itemType === BaseModel.TYPE_FOLDER) { deleteMessage = _('Delete notebook?'); } else if (itemType === BaseModel.TYPE_TAG) { deleteMessage = _('Remove this tag from all the notes?'); } else if (itemType === BaseModel.TYPE_SEARCH) { deleteMessage = _('Remove this search from the sidebar?'); } const menu = new Menu(); menu.append(new MenuItem({label: _('Delete'), click: async () => { const ok = bridge().showConfirmMessageBox(deleteMessage); if (!ok) return; if (itemType === BaseModel.TYPE_FOLDER) { await Folder.delete(itemId); } else if (itemType === BaseModel.TYPE_TAG) { await Tag.untagAll(itemId); } else if (itemType === BaseModel.TYPE_SEARCH) { this.props.dispatch({ type: 'SEARCH_DELETE', id: itemId, }); } }})) if (itemType === BaseModel.TYPE_FOLDER) { menu.append(new MenuItem({label: _('Rename'), click: async () => { this.props.dispatch({ type: 'WINDOW_COMMAND', name: 'renameNotebook', id: itemId, }); }})) } menu.popup(bridge().window()); } folderItem_click(folder) { this.props.dispatch({ type: 'FOLDER_SELECT', id: folder ? folder.id : null, }); } tagItem_click(tag) { this.props.dispatch({ type: 'TAG_SELECT', id: tag ? tag.id : null, }); } searchItem_click(search) { this.props.dispatch({ type: 'SEARCH_SELECT', id: search ? search.id : null, }); } async sync_click() { await shared.synchronize_press(this); } folderItem(folder, selected) { let style = Object.assign({}, this.style().listItem); if (selected) style = Object.assign(style, this.style().listItemSelected); if (folder.id === Folder.conflictFolderId()) style = Object.assign(style, this.style().conflictFolder); const onDragOver = (event, folder) => { if (event.dataTransfer.types.indexOf('text/x-jop-note-ids') >= 0) event.preventDefault(); } const onDrop = async (event, folder) => { if (event.dataTransfer.types.indexOf('text/x-jop-note-ids') < 0) return; event.preventDefault(); const noteIds = JSON.parse(event.dataTransfer.getData('text/x-jop-note-ids')); for (let i = 0; i < noteIds.length; i++) { await Note.moveToFolder(noteIds[i], folder.id); } } return { onDragOver(event, folder) } } onDrop={(event) => { onDrop(event, folder) } } href="#" data-id={folder.id} data-type={BaseModel.TYPE_FOLDER} onContextMenu={(event) => this.itemContextMenu(event)} key={folder.id} style={style} onClick={() => {this.folderItem_click(folder)}}>{folder.title} } tagItem(tag, selected) { let style = Object.assign({}, this.style().listItem); if (selected) style = Object.assign(style, this.style().listItemSelected); return this.itemContextMenu(event)} key={tag.id} style={style} onClick={() => {this.tagItem_click(tag)}}>{tag.title} } searchItem(search, selected) { let style = Object.assign({}, this.style().listItem); if (selected) style = Object.assign(style, this.style().listItemSelected); return this.itemContextMenu(event)} key={search.id} style={style} onClick={() => {this.searchItem_click(search)}}>{search.title} } makeDivider(key) { return
} makeHeader(key, label, iconName) { const style = this.style().header; const icon = return